@angular-wave/angular.ts 0.9.3 → 0.9.4
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/angular.d.ts +4 -19
- package/@types/animations/animate.d.ts +2 -2
- package/@types/animations/animation.d.ts +1 -1
- package/@types/core/compile/attributes.d.ts +1 -1
- package/@types/core/compile/compile.d.ts +2 -2
- package/@types/core/controller/controller.d.ts +1 -1
- package/@types/core/controller/interface.d.ts +6 -0
- package/@types/core/di/ng-module.d.ts +27 -26
- package/@types/core/filter/filter.d.ts +5 -5
- package/@types/core/interpolate/interface.d.ts +13 -0
- package/@types/core/interpolate/interpolate.d.ts +1 -13
- package/@types/core/scope/scope.d.ts +4 -1
- package/@types/directive/http/http.d.ts +16 -16
- package/@types/directive/http/interface.d.ts +27 -0
- package/@types/directive/include/include.d.ts +4 -4
- package/@types/directive/inject/inject.d.ts +12 -0
- package/@types/directive/model/model.d.ts +1 -1
- package/@types/directive/script/script.d.ts +2 -2
- package/@types/directive/setter/setter.d.ts +4 -4
- package/@types/filters/filter.d.ts +2 -2
- package/@types/filters/filters.d.ts +2 -2
- package/@types/filters/interface.d.ts +8 -0
- package/@types/filters/limit-to.d.ts +2 -2
- package/@types/filters/order-by.d.ts +2 -2
- package/@types/index.d.ts +84 -1
- package/@types/interface.d.ts +105 -82
- package/@types/router/state/interface.d.ts +8 -8
- package/@types/router/state-filters.d.ts +4 -4
- package/@types/router/template-factory.d.ts +6 -6
- package/@types/router/transition/hook-builder.d.ts +5 -2
- package/@types/router/transition/hook-registry.d.ts +11 -2
- package/@types/router/transition/transition-service.d.ts +6 -2
- package/@types/router/transition/transition.d.ts +2 -2
- package/@types/router/view/view.d.ts +1 -8
- package/@types/router/view-scroll.d.ts +4 -2
- package/@types/services/{anchor-scroll.d.ts → anchor-scroll/anchor-scroll.d.ts} +2 -2
- package/@types/services/exception/exception-handler.d.ts +2 -2
- package/@types/services/exception/interface.d.ts +1 -1
- package/@types/services/http/http.d.ts +40 -2
- package/@types/services/http/interface.d.ts +11 -0
- package/@types/services/location/location.d.ts +1 -4
- package/@types/services/sce/sce.d.ts +3 -4
- package/@types/services/template-cache/template-cache.d.ts +4 -4
- package/@types/services/template-request/interface.d.ts +22 -0
- package/@types/services/{template-request.d.ts → template-request/template-request.d.ts} +4 -7
- package/@types/shared/common.d.ts +8 -69
- package/@types/shared/hof.d.ts +7 -7
- package/dist/angular-ts.esm.js +509 -569
- package/dist/angular-ts.umd.js +509 -569
- package/dist/angular-ts.umd.min.js +1 -1
- package/{src/filters → docs/content/docs/filter}/filter.md +18 -9
- package/{src/filters → docs/content/docs/filter}/json.md +6 -3
- package/docs/content/docs/filter/limit-to.md +30 -0
- package/docs/content/docs/filter/order-by.md +123 -0
- package/docs/content/docs/provider/sceProvider.md +194 -0
- package/docs/content/docs/provider/templateRequestProvider.md +5 -0
- package/docs/content/docs/service/compile.md +5 -0
- package/docs/content/docs/service/controller.md +5 -0
- package/docs/content/docs/service/http.md +161 -0
- package/docs/content/docs/service/interpolation.md +5 -0
- package/docs/content/docs/service/log.md +1 -1
- package/docs/content/docs/service/parse.md +5 -0
- package/docs/content/docs/service/rootElement.md +5 -0
- package/docs/content/docs/service/rootScope.md +5 -0
- package/docs/content/docs/service/sce.md +194 -0
- package/docs/content/docs/service/templateRequest.md +5 -0
- package/docs/content/docs/values/_index.md +4 -0
- package/docs/content/docs/values/document.md +29 -0
- package/docs/content/docs/values/window.md +29 -0
- package/docs/layouts/shortcodes/version.html +1 -1
- package/docs/static/examples/document/document.html +3 -0
- package/docs/static/examples/i18n/i18n.html +77 -0
- package/docs/static/examples/window/window.html +4 -0
- package/docs/static/typedoc/assets/hierarchy.js +1 -1
- package/docs/static/typedoc/assets/highlight.css +0 -49
- package/docs/static/typedoc/assets/navigation.js +1 -1
- package/docs/static/typedoc/assets/search.js +1 -1
- package/docs/static/typedoc/classes/PubSubProvider.html +3 -2
- package/docs/static/typedoc/classes/TemplateCacheProvider.html +1 -1
- package/docs/static/typedoc/hierarchy.html +1 -1
- package/docs/static/typedoc/index.html +1 -1
- package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +1 -1
- package/docs/static/typedoc/interfaces/RequestConfig.html +1 -1
- package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +1 -1
- package/docs/static/typedoc/interfaces/ServiceProvider.html +3 -3
- package/docs/static/typedoc/types/HttpParamSerializer.html +2 -0
- package/docs/static/typedoc/types/{Expression.html → HttpParams.html} +1 -5
- package/legacy.d.ts +0 -921
- package/package.json +1 -1
- package/src/angular.js +2 -9
- package/src/animations/animate.js +1 -1
- package/src/animations/animation.js +7 -7
- package/src/core/compile/compile.js +3 -2
- package/src/core/controller/controller.js +10 -6
- package/src/core/controller/interface.ts +6 -0
- package/src/core/di/injector.js +1 -1
- package/src/core/di/internal-injector.js +2 -0
- package/src/core/di/ng-module.js +16 -13
- package/src/core/filter/filter.js +3 -3
- package/src/core/interpolate/interface.ts +14 -0
- package/src/core/interpolate/interpolate.js +7 -5
- package/src/core/scope/scope.js +4 -1
- package/src/directive/http/delete.spec.js +5 -8
- package/src/directive/http/http.js +16 -16
- package/src/directive/http/interface.ts +36 -0
- package/src/directive/http/put.spec.js +5 -8
- package/src/directive/include/include.js +2 -2
- package/src/{services/http-backend/http-backend.html → directive/inject/inject.html} +1 -4
- package/src/directive/inject/inject.js +35 -0
- package/src/directive/inject/inject.spec.js +108 -0
- package/src/{services/http-backend/http-backend.test.js → directive/inject/inject.test.js} +1 -1
- package/src/directive/script/script.js +1 -1
- package/src/directive/setter/setter.js +2 -2
- package/src/filters/filter.js +1 -1
- package/src/filters/filters.js +1 -1
- package/src/filters/interface.ts +9 -0
- package/src/filters/limit-to.js +1 -1
- package/src/filters/order-by.js +1 -1
- package/src/index.ts +96 -0
- package/src/injection-tokens.js +4 -1
- package/src/interface.ts +102 -93
- package/src/ng.js +6 -4
- package/src/ng.spec.js +12 -0
- package/src/router/directives/state-directives.js +1 -1
- package/src/router/directives/view-directive.spec.js +19 -35
- package/src/router/state/interface.ts +8 -8
- package/src/router/state/state-builder.js +4 -4
- package/src/router/state/state-registry.js +7 -2
- package/src/router/state/state-service.js +2 -14
- package/src/router/state-filters.js +2 -2
- package/src/router/template-factory.js +3 -3
- package/src/router/template-factory.spec.js +10 -19
- package/src/router/transition/hook-builder.js +5 -1
- package/src/router/transition/hook-registry.js +12 -3
- package/src/router/transition/transition-service.js +4 -9
- package/src/router/transition/transition.js +3 -2
- package/src/router/url/url-service.js +2 -2
- package/src/router/view/view.js +3 -15
- package/src/router/view-scroll.js +2 -2
- package/src/services/{anchor-scroll.js → anchor-scroll/anchor-scroll.js} +4 -4
- package/src/services/exception/exception-handler.js +1 -1
- package/src/services/exception/interface.ts +1 -1
- package/src/services/http/http.js +200 -13
- package/src/services/http/http.spec.js +388 -9
- package/src/services/http/interface.ts +13 -0
- package/src/services/location/location.js +1 -1
- package/src/services/sce/sce.js +18 -13
- package/src/services/template-cache/template-cache.js +2 -2
- package/src/services/template-request/interface.ts +23 -0
- package/src/services/{template-request.js → template-request/template-request.js} +6 -6
- package/src/shared/common.js +7 -80
- package/src/shared/hof.js +23 -17
- package/typedoc.json +1 -1
- package/@types/services/cookie-reader.d.ts +0 -4
- package/@types/services/http-backend/http-backend.d.ts +0 -58
- package/@types/services/template-cache/interface.d.ts +0 -10
- package/docs/static/typedoc/interfaces/ChangesObject.html +0 -6
- package/docs/static/typedoc/interfaces/ComponentOptions.html +0 -16
- package/docs/static/typedoc/interfaces/Controller.html +0 -12
- package/docs/static/typedoc/interfaces/Directive.html +0 -37
- package/docs/static/typedoc/interfaces/DirectivePrePost.html +0 -4
- package/docs/static/typedoc/interfaces/NgModelController.html +0 -30
- package/docs/static/typedoc/interfaces/NgModelOptions.html +0 -16
- package/docs/static/typedoc/interfaces/Provider.html +0 -34
- package/docs/static/typedoc/interfaces/TemplateCache.html +0 -7
- package/docs/static/typedoc/interfaces/TranscludeFunctionObject.html +0 -8
- package/docs/static/typedoc/types/AnnotatedDirectiveFactory.html +0 -1
- package/docs/static/typedoc/types/AnnotatedFactory.html +0 -8
- package/docs/static/typedoc/types/CloneAttachFunction.html +0 -2
- package/docs/static/typedoc/types/ControllerConstructor.html +0 -2
- package/docs/static/typedoc/types/DirectiveCompileFn.html +0 -2
- package/docs/static/typedoc/types/DirectiveController.html +0 -2
- package/docs/static/typedoc/types/DirectiveFactory.html +0 -1
- package/docs/static/typedoc/types/DirectiveFactoryFn.html +0 -1
- package/docs/static/typedoc/types/DirectiveLinkFn.html +0 -2
- package/docs/static/typedoc/types/ExpandoStore.html +0 -2
- package/docs/static/typedoc/types/FilterFactory.html +0 -2
- package/docs/static/typedoc/types/FilterFn.html +0 -2
- package/docs/static/typedoc/types/Injectable.html +0 -4
- package/docs/static/typedoc/types/InjectableClass.html +0 -1
- package/docs/static/typedoc/types/InjectableFactory.html +0 -1
- package/docs/static/typedoc/types/OnChangesObject.html +0 -2
- package/docs/static/typedoc/types/SwapModeType.html +0 -2
- package/docs/static/typedoc/types/TController.html +0 -2
- package/docs/static/typedoc/variables/SwapMode.html +0 -11
- package/src/filters/limit-to.md +0 -19
- package/src/filters/order-by.md +0 -83
- package/src/router/state/README.md +0 -21
- package/src/services/cookie-reader.js +0 -48
- package/src/services/http/http.md +0 -413
- package/src/services/http-backend/http-backend.js +0 -158
- package/src/services/http-backend/http-backend.spec.js +0 -389
- package/src/services/sce/sce.md +0 -300
- package/src/services/template-cache/interface.ts +0 -10
- /package/src/services/{anchor-scroll.html → anchor-scroll/anchor-scroll.html} +0 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
trimEmptyHash,
|
|
3
|
+
urlIsAllowedOriginFactory,
|
|
4
|
+
} from "../../shared/url-utils/url-utils.js";
|
|
2
5
|
import {
|
|
3
6
|
minErr,
|
|
4
7
|
isObject,
|
|
@@ -20,8 +23,10 @@ import {
|
|
|
20
23
|
uppercase,
|
|
21
24
|
isPromiseLike,
|
|
22
25
|
} from "../../shared/utils.js";
|
|
23
|
-
import {
|
|
26
|
+
import { $injectTokens as $t } from "../../injection-tokens.js";
|
|
24
27
|
|
|
28
|
+
let lastCookies = {};
|
|
29
|
+
let lastCookieString = "";
|
|
25
30
|
const APPLICATION_JSON = "application/json";
|
|
26
31
|
const CONTENT_TYPE_APPLICATION_JSON = {
|
|
27
32
|
"Content-Type": `${APPLICATION_JSON};charset=utf-8`,
|
|
@@ -53,8 +58,12 @@ function serializeValue(v) {
|
|
|
53
58
|
* Note that serializer will sort the request parameters alphabetically.
|
|
54
59
|
*/
|
|
55
60
|
export function HttpParamSerializerProvider() {
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
/**
|
|
62
|
+
* @returns {import('./interface.ts').HttpParamSerializer}
|
|
63
|
+
* A function that serializes parameters into a query string.
|
|
64
|
+
*/
|
|
65
|
+
this.$get = () => {
|
|
66
|
+
return (params) => {
|
|
58
67
|
if (!params) return "";
|
|
59
68
|
const parts = [];
|
|
60
69
|
Object.keys(params)
|
|
@@ -380,17 +389,15 @@ export function HttpProvider() {
|
|
|
380
389
|
});
|
|
381
390
|
|
|
382
391
|
this.$get = [
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"$sce",
|
|
392
|
+
$t.$injector,
|
|
393
|
+
$t.$sce,
|
|
386
394
|
/**
|
|
387
395
|
*
|
|
388
|
-
* @param {*} $httpBackend
|
|
389
396
|
* @param {import("../../core/di/internal-injector.js").InjectorService} $injector
|
|
390
397
|
* @param {*} $sce
|
|
391
398
|
* @returns
|
|
392
399
|
*/
|
|
393
|
-
function ($
|
|
400
|
+
function ($injector, $sce) {
|
|
394
401
|
/**
|
|
395
402
|
* @type {Map<string, string>}
|
|
396
403
|
*/
|
|
@@ -726,7 +733,7 @@ export function HttpProvider() {
|
|
|
726
733
|
* Makes the request.
|
|
727
734
|
*
|
|
728
735
|
* !!! ACCESSES CLOSURE VARS:
|
|
729
|
-
*
|
|
736
|
+
* defaults, $log, $rootScope, defaultCache, $http.pendingRequests
|
|
730
737
|
*/
|
|
731
738
|
function sendReq(config, reqData) {
|
|
732
739
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
@@ -797,7 +804,7 @@ export function HttpProvider() {
|
|
|
797
804
|
xsrfValue;
|
|
798
805
|
}
|
|
799
806
|
|
|
800
|
-
|
|
807
|
+
http(
|
|
801
808
|
config.method,
|
|
802
809
|
url,
|
|
803
810
|
reqData,
|
|
@@ -813,6 +820,10 @@ export function HttpProvider() {
|
|
|
813
820
|
|
|
814
821
|
return promise;
|
|
815
822
|
|
|
823
|
+
/**
|
|
824
|
+
* @param eventHandlers
|
|
825
|
+
* @return {Record<string, EventListener>}
|
|
826
|
+
*/
|
|
816
827
|
function createApplyHandlers(eventHandlers) {
|
|
817
828
|
if (eventHandlers) {
|
|
818
829
|
const applyHandlers = {};
|
|
@@ -829,12 +840,14 @@ export function HttpProvider() {
|
|
|
829
840
|
}
|
|
830
841
|
};
|
|
831
842
|
});
|
|
832
|
-
return applyHandlers;
|
|
843
|
+
return /** @type {Record<string, EventListener>} */ (applyHandlers);
|
|
844
|
+
} else {
|
|
845
|
+
return {};
|
|
833
846
|
}
|
|
834
847
|
}
|
|
835
848
|
|
|
836
849
|
/**
|
|
837
|
-
* Callback registered to
|
|
850
|
+
* Callback registered to http():
|
|
838
851
|
* - caches the response if desired
|
|
839
852
|
* - resolves the raw $http promise
|
|
840
853
|
* - calls $apply
|
|
@@ -920,3 +933,177 @@ export function HttpProvider() {
|
|
|
920
933
|
},
|
|
921
934
|
];
|
|
922
935
|
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Makes an HTTP request using XMLHttpRequest with flexible options.
|
|
939
|
+
*
|
|
940
|
+
* @param {string} method - The HTTP method (e.g., "GET", "POST").
|
|
941
|
+
* @param {string} [url] - The URL to send the request to. Defaults to the current page URL.
|
|
942
|
+
* @param {*} [post] - The body to send with the request, if any.
|
|
943
|
+
* @param {function(number, any, string|null, string, string): void} [callback] - Callback invoked when the request completes.
|
|
944
|
+
* @param {Object<string, string|undefined>} [headers] - Headers to set on the request.
|
|
945
|
+
* @param {number|Promise<any>} [timeout] - Timeout in ms or a cancellable promise.
|
|
946
|
+
* @param {boolean} [withCredentials] - Whether to send credentials with the request.
|
|
947
|
+
* @param {XMLHttpRequestResponseType} [responseType] - The type of data expected in the response.
|
|
948
|
+
* @param {Record<string, EventListener>} [eventHandlers] - Event listeners for the XMLHttpRequest object.
|
|
949
|
+
* @param {Record<string, EventListener>} [uploadEventHandlers] - Event listeners for the XMLHttpRequest.upload object.
|
|
950
|
+
* @returns {void}
|
|
951
|
+
*/
|
|
952
|
+
export function http(
|
|
953
|
+
method,
|
|
954
|
+
url,
|
|
955
|
+
post,
|
|
956
|
+
callback,
|
|
957
|
+
headers,
|
|
958
|
+
timeout,
|
|
959
|
+
withCredentials,
|
|
960
|
+
responseType,
|
|
961
|
+
eventHandlers,
|
|
962
|
+
uploadEventHandlers,
|
|
963
|
+
) {
|
|
964
|
+
url = url || trimEmptyHash(window.location.href);
|
|
965
|
+
|
|
966
|
+
const xhr = new XMLHttpRequest();
|
|
967
|
+
let abortedByTimeout = false;
|
|
968
|
+
let timeoutId;
|
|
969
|
+
|
|
970
|
+
xhr.open(method, url, true);
|
|
971
|
+
|
|
972
|
+
if (headers) {
|
|
973
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
974
|
+
if (isDefined(value)) {
|
|
975
|
+
xhr.setRequestHeader(key, value);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
xhr.onload = () => {
|
|
981
|
+
let status = xhr.status || 0;
|
|
982
|
+
const statusText = xhr.statusText || "";
|
|
983
|
+
|
|
984
|
+
if (status === 0) {
|
|
985
|
+
status = xhr.response ? 200 : new URL(url).protocol === "file:" ? 404 : 0;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
completeRequest(
|
|
989
|
+
status,
|
|
990
|
+
xhr.response,
|
|
991
|
+
xhr.getAllResponseHeaders(),
|
|
992
|
+
statusText,
|
|
993
|
+
"complete",
|
|
994
|
+
);
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
xhr.onerror = () => completeRequest(-1, null, null, "", "error");
|
|
998
|
+
xhr.ontimeout = () => completeRequest(-1, null, null, "", "timeout");
|
|
999
|
+
|
|
1000
|
+
xhr.onabort = () => {
|
|
1001
|
+
completeRequest(-1, null, null, "", abortedByTimeout ? "timeout" : "abort");
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
if (eventHandlers) {
|
|
1005
|
+
for (const [key, handler] of Object.entries(eventHandlers)) {
|
|
1006
|
+
xhr.addEventListener(key, handler);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
if (uploadEventHandlers) {
|
|
1011
|
+
for (const [key, handler] of Object.entries(uploadEventHandlers)) {
|
|
1012
|
+
xhr.upload.addEventListener(key, handler);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
if (withCredentials) {
|
|
1017
|
+
xhr.withCredentials = true;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
if (responseType) {
|
|
1021
|
+
try {
|
|
1022
|
+
xhr.responseType = responseType;
|
|
1023
|
+
} catch (e) {
|
|
1024
|
+
if (responseType !== "json") throw e;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
xhr.send(isUndefined(post) ? null : post);
|
|
1029
|
+
|
|
1030
|
+
if (typeof timeout === "number" && timeout > 0) {
|
|
1031
|
+
timeoutId = setTimeout(() => timeoutRequest("timeout"), timeout);
|
|
1032
|
+
} else if (isPromiseLike(timeout)) {
|
|
1033
|
+
/** @type {Promise} */ (timeout).then(() => {
|
|
1034
|
+
timeoutRequest(isDefined(timeout["$$timeoutId"]) ? "timeout" : "abort");
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* @param {"timeout"|"abort"} reason
|
|
1040
|
+
*/
|
|
1041
|
+
function timeoutRequest(reason) {
|
|
1042
|
+
abortedByTimeout = reason === "timeout";
|
|
1043
|
+
if (xhr) xhr.abort();
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* @param {number} status - HTTP status code or -1 for network errors.
|
|
1048
|
+
* @param {*} response - The parsed or raw response from the server.
|
|
1049
|
+
* @param {string|null} headersString - The raw response headers as a string.
|
|
1050
|
+
* @param {string} statusText - The status text returned by the server.
|
|
1051
|
+
* @param {"complete"|"error"|"timeout"|"abort"} xhrStatus - Final status of the request.
|
|
1052
|
+
*/
|
|
1053
|
+
function completeRequest(
|
|
1054
|
+
status,
|
|
1055
|
+
response,
|
|
1056
|
+
headersString,
|
|
1057
|
+
statusText,
|
|
1058
|
+
xhrStatus,
|
|
1059
|
+
) {
|
|
1060
|
+
if (isDefined(timeoutId)) {
|
|
1061
|
+
clearTimeout(timeoutId);
|
|
1062
|
+
}
|
|
1063
|
+
callback(status, response, headersString, statusText, xhrStatus);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* @returns {Object<String, String>} List of all cookies
|
|
1069
|
+
*/
|
|
1070
|
+
function getCookies() {
|
|
1071
|
+
let cookieArray;
|
|
1072
|
+
let cookie;
|
|
1073
|
+
let i;
|
|
1074
|
+
let index;
|
|
1075
|
+
let name;
|
|
1076
|
+
const currentCookieString = document.cookie;
|
|
1077
|
+
|
|
1078
|
+
if (currentCookieString !== lastCookieString) {
|
|
1079
|
+
lastCookieString = currentCookieString;
|
|
1080
|
+
cookieArray = lastCookieString.split("; ");
|
|
1081
|
+
lastCookies = {};
|
|
1082
|
+
|
|
1083
|
+
for (i = 0; i < cookieArray.length; i++) {
|
|
1084
|
+
cookie = cookieArray[i];
|
|
1085
|
+
index = cookie.indexOf("=");
|
|
1086
|
+
if (index > 0) {
|
|
1087
|
+
// ignore nameless cookies
|
|
1088
|
+
name = safeDecodeURIComponent(cookie.substring(0, index));
|
|
1089
|
+
// the first value that is seen for a cookie is the most
|
|
1090
|
+
// specific one. values for the same cookie name that
|
|
1091
|
+
// follow are for less specific paths.
|
|
1092
|
+
if (isUndefined(lastCookies[name])) {
|
|
1093
|
+
lastCookies[name] = safeDecodeURIComponent(
|
|
1094
|
+
cookie.substring(index + 1),
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
return lastCookies;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
function safeDecodeURIComponent(str) {
|
|
1104
|
+
try {
|
|
1105
|
+
return decodeURIComponent(str);
|
|
1106
|
+
} catch {
|
|
1107
|
+
return str;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
@@ -2,23 +2,17 @@ import { createInjector } from "../../core/di/injector.js";
|
|
|
2
2
|
import { isObject } from "../../shared/utils.js";
|
|
3
3
|
import { Angular } from "../../angular.js";
|
|
4
4
|
import { wait } from "../../shared/test-utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let ajaxEntries = performance
|
|
8
|
-
.getEntriesByType("resource")
|
|
9
|
-
.filter((entry) => entry.initiatorType === "xmlhttprequest");
|
|
10
|
-
return ajaxEntries[ajaxEntries.length - 1];
|
|
11
|
-
}
|
|
5
|
+
import { http } from "./http.js";
|
|
6
|
+
import sinon from "sinon";
|
|
12
7
|
|
|
13
8
|
describe("$http", function () {
|
|
14
|
-
let $http, $injector,
|
|
9
|
+
let $http, $injector, requests, response, $rootScope;
|
|
15
10
|
|
|
16
11
|
beforeEach(function () {
|
|
17
12
|
window.angular = new Angular();
|
|
18
13
|
requests = [];
|
|
19
14
|
$injector = createInjector(["ng"]);
|
|
20
15
|
$http = $injector.get("$http");
|
|
21
|
-
$httpBackend = $injector.get("$httpBackend");
|
|
22
16
|
$rootScope = $injector.get("$rootScope");
|
|
23
17
|
});
|
|
24
18
|
|
|
@@ -1143,6 +1137,391 @@ describe("$http", function () {
|
|
|
1143
1137
|
});
|
|
1144
1138
|
});
|
|
1145
1139
|
|
|
1140
|
+
describe("http", () => {
|
|
1141
|
+
let $backend;
|
|
1142
|
+
let xhr;
|
|
1143
|
+
let callback;
|
|
1144
|
+
let requests;
|
|
1145
|
+
let angular;
|
|
1146
|
+
|
|
1147
|
+
beforeEach(() => {
|
|
1148
|
+
xhr = sinon.useFakeXMLHttpRequest();
|
|
1149
|
+
requests = [];
|
|
1150
|
+
xhr.onCreate = function (req) {
|
|
1151
|
+
requests.push(req);
|
|
1152
|
+
};
|
|
1153
|
+
angular = window.angular = new Angular();
|
|
1154
|
+
callback = jasmine.createSpy("done");
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
afterEach(() => {
|
|
1158
|
+
xhr.restore();
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
it("should do basics - open async xhr and send data", () => {
|
|
1162
|
+
http("GET", "/some-url", "some-data", () => {});
|
|
1163
|
+
expect(requests.length).toBe(1);
|
|
1164
|
+
expect(requests[0].method).toBe("GET");
|
|
1165
|
+
expect(requests[0].url).toBe("/some-url");
|
|
1166
|
+
expect(requests[0].requestBody).toBe("some-data");
|
|
1167
|
+
expect(requests[0].async).toBe(true);
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
it("should pass null to send if no body is set", () => {
|
|
1171
|
+
http("GET", "/some-url", undefined, () => {});
|
|
1172
|
+
expect(requests[0].requestBody).toBe(null);
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
it("should pass the correct falsy value to send if falsy body is set (excluding undefined, NaN)", () => {
|
|
1176
|
+
[false, 0, "", null].forEach((value, index) => {
|
|
1177
|
+
http("GET", "/some-url", value, () => {});
|
|
1178
|
+
expect(requests[index].requestBody).toBe(value);
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
it("should pass NaN to send if NaN body is set", () => {
|
|
1183
|
+
http("GET", "/some-url", NaN, () => {});
|
|
1184
|
+
expect(isNaN(requests[0].requestBody)).toEqual(true);
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
it("should call completion function with xhr.statusText if present", () => {
|
|
1188
|
+
callback.and.callFake((status, response, headers, statusText) => {
|
|
1189
|
+
expect(statusText).toBe("OK");
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
http("GET", "/some-url", null, callback);
|
|
1193
|
+
requests[0].respond(200);
|
|
1194
|
+
expect(callback).toHaveBeenCalled();
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
it("should set only the requested headers", () => {
|
|
1198
|
+
http("POST", "URL", null, () => {}, {
|
|
1199
|
+
"X-header1": "value1",
|
|
1200
|
+
"X-header2": "value2",
|
|
1201
|
+
});
|
|
1202
|
+
expect(requests[0].requestHeaders["X-header1"]).toEqual("value1");
|
|
1203
|
+
expect(requests[0].requestHeaders["X-header2"]).toEqual("value2");
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
it("should not try to read response data when request is aborted", () => {
|
|
1207
|
+
callback.and.callFake((status, response, headers, statusText) => {
|
|
1208
|
+
expect(status).toBe(-1);
|
|
1209
|
+
expect(response).toBe(null);
|
|
1210
|
+
expect(headers).toBe(null);
|
|
1211
|
+
expect(statusText).toBe("");
|
|
1212
|
+
});
|
|
1213
|
+
http("GET", "/url", null, callback, {}, 2000);
|
|
1214
|
+
requests[0].respond(0);
|
|
1215
|
+
expect(callback).toHaveBeenCalled();
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
it("should complete the request on abort", () => {
|
|
1219
|
+
callback.and.callFake(
|
|
1220
|
+
(status, response, headers, statusText, xhrStatus) => {
|
|
1221
|
+
expect(status).toBe(-1);
|
|
1222
|
+
expect(response).toBe(null);
|
|
1223
|
+
expect(headers).toBe(null);
|
|
1224
|
+
expect(statusText).toBe("");
|
|
1225
|
+
},
|
|
1226
|
+
);
|
|
1227
|
+
http("GET", "/url", null, callback, {});
|
|
1228
|
+
|
|
1229
|
+
expect(callback).not.toHaveBeenCalled();
|
|
1230
|
+
requests[0].error();
|
|
1231
|
+
expect(callback).toHaveBeenCalled();
|
|
1232
|
+
});
|
|
1233
|
+
|
|
1234
|
+
it("should complete the request on error", () => {
|
|
1235
|
+
callback.and.callFake(
|
|
1236
|
+
(status, response, headers, statusText, xhrStatus) => {
|
|
1237
|
+
expect(status).toBe(-1);
|
|
1238
|
+
expect(response).toBe(null);
|
|
1239
|
+
expect(headers).toBe(null);
|
|
1240
|
+
expect(statusText).toBe("");
|
|
1241
|
+
expect(xhrStatus).toBe("error");
|
|
1242
|
+
},
|
|
1243
|
+
);
|
|
1244
|
+
http("GET", "/url", null, callback, {});
|
|
1245
|
+
|
|
1246
|
+
expect(callback).not.toHaveBeenCalled();
|
|
1247
|
+
requests[0].error();
|
|
1248
|
+
expect(callback).toHaveBeenCalled();
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
it("should complete the request on success", () => {
|
|
1252
|
+
callback.and.callFake(
|
|
1253
|
+
(status, response, headers, statusText, xhrStatus) => {
|
|
1254
|
+
expect(status).toBe(200);
|
|
1255
|
+
expect(response).toBe("response");
|
|
1256
|
+
expect(headers).toBe("");
|
|
1257
|
+
expect(statusText).toBe("OK");
|
|
1258
|
+
expect(xhrStatus).toBe("complete");
|
|
1259
|
+
},
|
|
1260
|
+
);
|
|
1261
|
+
http("GET", "/url", null, callback, {});
|
|
1262
|
+
|
|
1263
|
+
expect(callback).not.toHaveBeenCalled();
|
|
1264
|
+
requests[0].respond(200, "", "response");
|
|
1265
|
+
expect(callback).toHaveBeenCalled();
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1268
|
+
// it("should set withCredentials", () => {
|
|
1269
|
+
// $backend("GET", "/some.url", null, callback, {}, null, true);
|
|
1270
|
+
// expect(requests[0].withCredentials).toBeTrue();
|
|
1271
|
+
// });
|
|
1272
|
+
|
|
1273
|
+
// it("should abort request on $timeout promise resolution", () => {
|
|
1274
|
+
// callback.and.callFake(
|
|
1275
|
+
// (status, response, headers, statusText, xhrStatus) => {
|
|
1276
|
+
// expect(status).toBe(-1);
|
|
1277
|
+
// expect(xhrStatus).toBe("timeout");
|
|
1278
|
+
// },
|
|
1279
|
+
// );
|
|
1280
|
+
|
|
1281
|
+
// $backend(
|
|
1282
|
+
// "GET",
|
|
1283
|
+
// "/url",
|
|
1284
|
+
// null,
|
|
1285
|
+
// callback,
|
|
1286
|
+
// {},
|
|
1287
|
+
// setTimeout(() => {}, 2000),
|
|
1288
|
+
// );
|
|
1289
|
+
// spyOn(xhr, "abort");
|
|
1290
|
+
// expect(xhr.abort).toHaveBeenCalled();
|
|
1291
|
+
|
|
1292
|
+
// requests[0].abort();
|
|
1293
|
+
// expect(callback).toHaveBeenCalled();
|
|
1294
|
+
// });
|
|
1295
|
+
|
|
1296
|
+
// it("should not abort resolved request on timeout promise resolution", () => {
|
|
1297
|
+
// callback.and.callFake((status, response) => {
|
|
1298
|
+
// expect(status).toBe(200);
|
|
1299
|
+
// });
|
|
1300
|
+
|
|
1301
|
+
// $backend(
|
|
1302
|
+
// "GET",
|
|
1303
|
+
// "/url",
|
|
1304
|
+
// null,
|
|
1305
|
+
// callback,
|
|
1306
|
+
// {},
|
|
1307
|
+
// setTimeout(() => {}, 2000),
|
|
1308
|
+
// );
|
|
1309
|
+
// xhr = MockXhr.$$lastInstance;
|
|
1310
|
+
// spyOn(xhr, "abort");
|
|
1311
|
+
|
|
1312
|
+
// xhr.status = 200;
|
|
1313
|
+
// xhr.onload();
|
|
1314
|
+
// expect(callback).toHaveBeenCalled();
|
|
1315
|
+
|
|
1316
|
+
// $timeout.flush();
|
|
1317
|
+
// expect(xhr.abort).not.toHaveBeenCalled();
|
|
1318
|
+
// });
|
|
1319
|
+
|
|
1320
|
+
// it("should abort request on canceler promise resolution", () => {
|
|
1321
|
+
// const canceler = Promise.withResolvers();
|
|
1322
|
+
|
|
1323
|
+
// callback.and.callFake(
|
|
1324
|
+
// (status, response, headers, statusText, xhrStatus) => {
|
|
1325
|
+
// expect(status).toBe(-1);
|
|
1326
|
+
// expect(xhrStatus).toBe("abort");
|
|
1327
|
+
// },
|
|
1328
|
+
// );
|
|
1329
|
+
|
|
1330
|
+
// $backend("GET", "/url", null, callback, {}, canceler.promise);
|
|
1331
|
+
// xhr = MockXhr.$$lastInstance;
|
|
1332
|
+
|
|
1333
|
+
// canceler.resolve();
|
|
1334
|
+
// $browser.defer.flush();
|
|
1335
|
+
|
|
1336
|
+
// expect(callback).toHaveBeenCalled();
|
|
1337
|
+
// });
|
|
1338
|
+
|
|
1339
|
+
// it("should cancel timeout on completion", () => {
|
|
1340
|
+
// callback.and.callFake((status, response) => {
|
|
1341
|
+
// expect(status).toBe(200);
|
|
1342
|
+
// });
|
|
1343
|
+
|
|
1344
|
+
// $backend("GET", "/url", null, callback, {}, 2000);
|
|
1345
|
+
// xhr = MockXhr.$$lastInstance;
|
|
1346
|
+
// spyOn(xhr, "abort");
|
|
1347
|
+
|
|
1348
|
+
// expect($browser.deferredFns[0].time).toBe(2000);
|
|
1349
|
+
|
|
1350
|
+
// xhr.status = 200;
|
|
1351
|
+
// xhr.onload();
|
|
1352
|
+
// expect(callback).toHaveBeenCalled();
|
|
1353
|
+
|
|
1354
|
+
// expect($browser.deferredFns.length).toBe(0);
|
|
1355
|
+
// expect(xhr.abort).not.toHaveBeenCalled();
|
|
1356
|
+
// });
|
|
1357
|
+
|
|
1358
|
+
// it('should call callback with xhrStatus "abort" on explicit xhr.abort() when $timeout is set', () => {
|
|
1359
|
+
// callback.and.callFake(
|
|
1360
|
+
// (status, response, headers, statusText, xhrStatus) => {
|
|
1361
|
+
// expect(status).toBe(-1);
|
|
1362
|
+
// expect(xhrStatus).toBe("abort");
|
|
1363
|
+
// },
|
|
1364
|
+
// );
|
|
1365
|
+
|
|
1366
|
+
// $backend(
|
|
1367
|
+
// "GET",
|
|
1368
|
+
// "/url",
|
|
1369
|
+
// null,
|
|
1370
|
+
// callback,
|
|
1371
|
+
// {},
|
|
1372
|
+
// setTimeout(() => {}, 2000),
|
|
1373
|
+
// );
|
|
1374
|
+
// spyOn(xhr, "abort").and.callThrough();
|
|
1375
|
+
|
|
1376
|
+
// xhr.abort();
|
|
1377
|
+
|
|
1378
|
+
// expect(callback).toHaveBeenCalled();
|
|
1379
|
+
// });
|
|
1380
|
+
|
|
1381
|
+
it("should set up event listeners", () => {
|
|
1382
|
+
const progressFn = function () {
|
|
1383
|
+
"progressFn";
|
|
1384
|
+
};
|
|
1385
|
+
http("GET", "/url", null, callback, {}, null, null, null, {
|
|
1386
|
+
progress: progressFn,
|
|
1387
|
+
});
|
|
1388
|
+
expect(requests[0].eventListeners.progress[1].listener).toBe(progressFn);
|
|
1389
|
+
//expect(requests[0].eventListeners.progress[1].listener).toBe(uploadProgressFn);
|
|
1390
|
+
});
|
|
1391
|
+
|
|
1392
|
+
// describe("responseType", () => {
|
|
1393
|
+
// it("should set responseType and return xhr.response", () => {
|
|
1394
|
+
// $backend("GET", "/whatever", null, callback, {}, null, null, "blob");
|
|
1395
|
+
|
|
1396
|
+
// const xhrInstance = MockXhr.$$lastInstance;
|
|
1397
|
+
// expect(xhrInstance.responseType).toBe("blob");
|
|
1398
|
+
|
|
1399
|
+
// callback.and.callFake((status, response) => {
|
|
1400
|
+
// expect(response).toBe(xhrInstance.response);
|
|
1401
|
+
// });
|
|
1402
|
+
|
|
1403
|
+
// xhrInstance.response = { some: "object" };
|
|
1404
|
+
// xhrInstance.onload();
|
|
1405
|
+
|
|
1406
|
+
// expect(callback).toHaveBeenCalled();
|
|
1407
|
+
// });
|
|
1408
|
+
|
|
1409
|
+
// it("should read responseText if response was not defined", () => {
|
|
1410
|
+
// // old browsers like IE9, don't support responseType, so they always respond with responseText
|
|
1411
|
+
|
|
1412
|
+
// $backend("GET", "/whatever", null, callback, {}, null, null, "blob");
|
|
1413
|
+
|
|
1414
|
+
// const xhrInstance = MockXhr.$$lastInstance;
|
|
1415
|
+
// const responseText = '{"some": "object"}';
|
|
1416
|
+
// expect(xhrInstance.responseType).toBe("blob");
|
|
1417
|
+
|
|
1418
|
+
// callback.and.callFake((status, response) => {
|
|
1419
|
+
// expect(response).toBe(responseText);
|
|
1420
|
+
// });
|
|
1421
|
+
|
|
1422
|
+
// xhrInstance.responseText = responseText;
|
|
1423
|
+
// xhrInstance.onload();
|
|
1424
|
+
|
|
1425
|
+
// expect(callback).toHaveBeenCalled();
|
|
1426
|
+
// });
|
|
1427
|
+
// });
|
|
1428
|
+
|
|
1429
|
+
// describe("protocols that return 0 status code", () => {
|
|
1430
|
+
// function respond(status, content) {
|
|
1431
|
+
// xhr = MockXhr.$$lastInstance;
|
|
1432
|
+
// xhr.status = status;
|
|
1433
|
+
// xhr.responseText = content;
|
|
1434
|
+
// xhr.onload();
|
|
1435
|
+
// }
|
|
1436
|
+
|
|
1437
|
+
// beforeEach(() => {
|
|
1438
|
+
// $backend = createHttpBackend($browser, createMockXhr);
|
|
1439
|
+
// });
|
|
1440
|
+
|
|
1441
|
+
// it("should convert 0 to 200 if content and file protocol", () => {
|
|
1442
|
+
// $backend("GET", "file:///whatever/index.html", null, callback);
|
|
1443
|
+
// respond(0, "SOME CONTENT");
|
|
1444
|
+
|
|
1445
|
+
// expect(callback).toHaveBeenCalled();
|
|
1446
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(200);
|
|
1447
|
+
// });
|
|
1448
|
+
|
|
1449
|
+
// it("should convert 0 to 200 if content for protocols other than file", () => {
|
|
1450
|
+
// $backend("GET", "someProtocol:///whatever/index.html", null, callback);
|
|
1451
|
+
// respond(0, "SOME CONTENT");
|
|
1452
|
+
|
|
1453
|
+
// expect(callback).toHaveBeenCalled();
|
|
1454
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(200);
|
|
1455
|
+
// });
|
|
1456
|
+
|
|
1457
|
+
// it("should convert 0 to 404 if no content and file protocol", () => {
|
|
1458
|
+
// $backend("GET", "file:///whatever/index.html", null, callback);
|
|
1459
|
+
// respond(0, "");
|
|
1460
|
+
|
|
1461
|
+
// expect(callback).toHaveBeenCalled();
|
|
1462
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(404);
|
|
1463
|
+
// });
|
|
1464
|
+
|
|
1465
|
+
// it("should not convert 0 to 404 if no content for protocols other than file", () => {
|
|
1466
|
+
// $backend("GET", "someProtocol:///whatever/index.html", null, callback);
|
|
1467
|
+
// respond(0, "");
|
|
1468
|
+
|
|
1469
|
+
// expect(callback).toHaveBeenCalled();
|
|
1470
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(0);
|
|
1471
|
+
// });
|
|
1472
|
+
|
|
1473
|
+
// it("should convert 0 to 404 if no content - relative url", () => {
|
|
1474
|
+
// const originalUrlParsingNode = urlParsingNode;
|
|
1475
|
+
|
|
1476
|
+
// // temporarily overriding the DOM element to pretend that the test runs origin with file:// protocol
|
|
1477
|
+
// urlParsingNode = {
|
|
1478
|
+
// hash: "#/C:/",
|
|
1479
|
+
// host: "",
|
|
1480
|
+
// hostname: "",
|
|
1481
|
+
// href: "file:///C:/base#!/C:/foo",
|
|
1482
|
+
// pathname: "/C:/foo",
|
|
1483
|
+
// port: "",
|
|
1484
|
+
// protocol: "file:",
|
|
1485
|
+
// search: "",
|
|
1486
|
+
// setAttribute: () => {},
|
|
1487
|
+
// };
|
|
1488
|
+
|
|
1489
|
+
// try {
|
|
1490
|
+
// $backend("GET", "/whatever/index.html", null, callback);
|
|
1491
|
+
// respond(0, "");
|
|
1492
|
+
|
|
1493
|
+
// expect(callback).toHaveBeenCalled();
|
|
1494
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(404);
|
|
1495
|
+
// } finally {
|
|
1496
|
+
// urlParsingNode = originalUrlParsingNode;
|
|
1497
|
+
// }
|
|
1498
|
+
// });
|
|
1499
|
+
|
|
1500
|
+
// it("should return original backend status code if different from 0", () => {
|
|
1501
|
+
// // request to http://
|
|
1502
|
+
// $backend("POST", "http://rest_api/create_whatever", null, callback);
|
|
1503
|
+
// respond(201, "");
|
|
1504
|
+
|
|
1505
|
+
// expect(callback).toHaveBeenCalled();
|
|
1506
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(201);
|
|
1507
|
+
|
|
1508
|
+
// // request to file://
|
|
1509
|
+
// $backend("POST", "file://rest_api/create_whatever", null, callback);
|
|
1510
|
+
// respond(201, "");
|
|
1511
|
+
|
|
1512
|
+
// expect(callback).toHaveBeenCalled();
|
|
1513
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(201);
|
|
1514
|
+
|
|
1515
|
+
// // request to file:// with HTTP status >= 300
|
|
1516
|
+
// $backend("POST", "file://rest_api/create_whatever", null, callback);
|
|
1517
|
+
// respond(503, "");
|
|
1518
|
+
|
|
1519
|
+
// expect(callback).toHaveBeenCalled();
|
|
1520
|
+
// expect(callback.calls.mostRecent().args[0]).toBe(503);
|
|
1521
|
+
// });
|
|
1522
|
+
// });
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1146
1525
|
// describe("$http", () => {
|
|
1147
1526
|
// let callback;
|
|
1148
1527
|
// let mockedCookies;
|