@angular-wave/angular.ts 0.0.1
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/.eslintignore +1 -0
- package/.eslintrc.cjs +29 -0
- package/.github/workflows/playwright.yml +27 -0
- package/CHANGELOG.md +17974 -0
- package/CODE_OF_CONDUCT.md +3 -0
- package/CONTRIBUTING.md +246 -0
- package/DEVELOPERS.md +488 -0
- package/LICENSE +22 -0
- package/Makefile +31 -0
- package/README.md +115 -0
- package/RELEASE.md +98 -0
- package/SECURITY.md +16 -0
- package/TRIAGING.md +135 -0
- package/css/angular.css +22 -0
- package/dist/angular-ts.cjs.js +36843 -0
- package/dist/angular-ts.esm.js +36841 -0
- package/dist/angular-ts.umd.js +36848 -0
- package/dist/build/angular-animate.js +4272 -0
- package/dist/build/angular-aria.js +426 -0
- package/dist/build/angular-message-format.js +1072 -0
- package/dist/build/angular-messages.js +829 -0
- package/dist/build/angular-mocks.js +3757 -0
- package/dist/build/angular-parse-ext.js +1275 -0
- package/dist/build/angular-resource.js +911 -0
- package/dist/build/angular-route.js +1266 -0
- package/dist/build/angular-sanitize.js +891 -0
- package/dist/build/angular-touch.js +368 -0
- package/dist/build/angular.js +36600 -0
- package/e2e/unit.spec.ts +15 -0
- package/images/android-chrome-192x192.png +0 -0
- package/images/android-chrome-512x512.png +0 -0
- package/images/apple-touch-icon.png +0 -0
- package/images/favicon-16x16.png +0 -0
- package/images/favicon-32x32.png +0 -0
- package/images/favicon.ico +0 -0
- package/images/site.webmanifest +1 -0
- package/index.html +104 -0
- package/package.json +47 -0
- package/playwright.config.ts +78 -0
- package/public/circle.html +1 -0
- package/public/my_child_directive.html +1 -0
- package/public/my_directive.html +1 -0
- package/public/my_other_directive.html +1 -0
- package/public/test.html +1 -0
- package/rollup.config.js +31 -0
- package/src/animations/animateCache.js +55 -0
- package/src/animations/animateChildrenDirective.js +105 -0
- package/src/animations/animateCss.js +1139 -0
- package/src/animations/animateCssDriver.js +291 -0
- package/src/animations/animateJs.js +367 -0
- package/src/animations/animateJsDriver.js +67 -0
- package/src/animations/animateQueue.js +851 -0
- package/src/animations/animation.js +506 -0
- package/src/animations/module.js +779 -0
- package/src/animations/ngAnimateSwap.js +119 -0
- package/src/animations/rafScheduler.js +50 -0
- package/src/animations/shared.js +378 -0
- package/src/constants.js +20 -0
- package/src/core/animate.js +845 -0
- package/src/core/animateCss.js +73 -0
- package/src/core/animateRunner.js +195 -0
- package/src/core/attributes.js +199 -0
- package/src/core/cache.js +45 -0
- package/src/core/compile.js +4727 -0
- package/src/core/controller.js +225 -0
- package/src/core/exceptionHandler.js +63 -0
- package/src/core/filter.js +146 -0
- package/src/core/interpolate.js +442 -0
- package/src/core/interval.js +188 -0
- package/src/core/intervalFactory.js +57 -0
- package/src/core/location.js +1086 -0
- package/src/core/parser/parse.js +2562 -0
- package/src/core/parser/parse.md +13 -0
- package/src/core/q.js +746 -0
- package/src/core/rootScope.js +1596 -0
- package/src/core/sanitizeUri.js +85 -0
- package/src/core/sce.js +1161 -0
- package/src/core/taskTrackerFactory.js +125 -0
- package/src/core/timeout.js +121 -0
- package/src/core/urlUtils.js +187 -0
- package/src/core/utils.js +1349 -0
- package/src/directive/a.js +37 -0
- package/src/directive/attrs.js +283 -0
- package/src/directive/bind.js +51 -0
- package/src/directive/bind.md +142 -0
- package/src/directive/change.js +12 -0
- package/src/directive/change.md +25 -0
- package/src/directive/cloak.js +12 -0
- package/src/directive/cloak.md +24 -0
- package/src/directive/events.js +75 -0
- package/src/directive/events.md +166 -0
- package/src/directive/form.js +725 -0
- package/src/directive/init.js +15 -0
- package/src/directive/init.md +41 -0
- package/src/directive/input.js +1783 -0
- package/src/directive/list.js +46 -0
- package/src/directive/list.md +22 -0
- package/src/directive/ngClass.js +249 -0
- package/src/directive/ngController.js +64 -0
- package/src/directive/ngCsp.js +82 -0
- package/src/directive/ngIf.js +134 -0
- package/src/directive/ngInclude.js +217 -0
- package/src/directive/ngModel.js +1356 -0
- package/src/directive/ngModelOptions.js +509 -0
- package/src/directive/ngOptions.js +670 -0
- package/src/directive/ngRef.js +90 -0
- package/src/directive/ngRepeat.js +650 -0
- package/src/directive/ngShowHide.js +255 -0
- package/src/directive/ngSwitch.js +178 -0
- package/src/directive/ngTransclude.js +98 -0
- package/src/directive/non-bindable.js +11 -0
- package/src/directive/non-bindable.md +17 -0
- package/src/directive/script.js +30 -0
- package/src/directive/select.js +624 -0
- package/src/directive/style.js +25 -0
- package/src/directive/style.md +23 -0
- package/src/directive/validators.js +329 -0
- package/src/exts/aria.js +544 -0
- package/src/exts/messages.js +852 -0
- package/src/filters/filter.js +207 -0
- package/src/filters/filter.md +69 -0
- package/src/filters/filters.js +239 -0
- package/src/filters/json.md +16 -0
- package/src/filters/limit-to.js +43 -0
- package/src/filters/limit-to.md +19 -0
- package/src/filters/order-by.js +183 -0
- package/src/filters/order-by.md +83 -0
- package/src/index.js +13 -0
- package/src/injector.js +1034 -0
- package/src/jqLite.js +1117 -0
- package/src/loader.js +1320 -0
- package/src/public.js +215 -0
- package/src/routeToRegExp.js +41 -0
- package/src/services/anchorScroll.js +135 -0
- package/src/services/browser.js +321 -0
- package/src/services/cacheFactory.js +398 -0
- package/src/services/cookieReader.js +72 -0
- package/src/services/document.js +64 -0
- package/src/services/http.js +1537 -0
- package/src/services/httpBackend.js +206 -0
- package/src/services/log.js +160 -0
- package/src/services/templateRequest.js +139 -0
- package/test/angular.spec.js +2153 -0
- package/test/aria/aria.spec.js +1245 -0
- package/test/binding.spec.js +504 -0
- package/test/build-test.html +14 -0
- package/test/injector.spec.js +2327 -0
- package/test/jasmine/jasmine-5.1.2/boot0.js +65 -0
- package/test/jasmine/jasmine-5.1.2/boot1.js +133 -0
- package/test/jasmine/jasmine-5.1.2/jasmine-html.js +963 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.css +320 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.js +10824 -0
- package/test/jasmine/jasmine-5.1.2/jasmine_favicon.png +0 -0
- package/test/jasmine/jasmine-browser.json +17 -0
- package/test/jasmine/jasmine.json +9 -0
- package/test/jqlite.spec.js +2133 -0
- package/test/loader.spec.js +219 -0
- package/test/messages/messages.spec.js +1146 -0
- package/test/min-err.spec.js +174 -0
- package/test/mock-test.html +13 -0
- package/test/module-test.html +15 -0
- package/test/ng/anomate.spec.js +606 -0
- package/test/ng/cache-factor.spec.js +334 -0
- package/test/ng/compile.spec.js +17956 -0
- package/test/ng/controller-provider.spec.js +227 -0
- package/test/ng/cookie-reader.spec.js +98 -0
- package/test/ng/directive/a.spec.js +192 -0
- package/test/ng/directive/bind.spec.js +334 -0
- package/test/ng/directive/boolean.spec.js +136 -0
- package/test/ng/directive/change.spec.js +71 -0
- package/test/ng/directive/class.spec.js +858 -0
- package/test/ng/directive/click.spec.js +38 -0
- package/test/ng/directive/cloak.spec.js +44 -0
- package/test/ng/directive/constoller.spec.js +194 -0
- package/test/ng/directive/element-style.spec.js +92 -0
- package/test/ng/directive/event.spec.js +282 -0
- package/test/ng/directive/form.spec.js +1518 -0
- package/test/ng/directive/href.spec.js +143 -0
- package/test/ng/directive/if.spec.js +402 -0
- package/test/ng/directive/include.spec.js +828 -0
- package/test/ng/directive/init.spec.js +68 -0
- package/test/ng/directive/input.spec.js +3810 -0
- package/test/ng/directive/list.spec.js +170 -0
- package/test/ng/directive/model-options.spec.js +1008 -0
- package/test/ng/directive/model.spec.js +1905 -0
- package/test/ng/directive/non-bindable.spec.js +55 -0
- package/test/ng/directive/options.spec.js +3583 -0
- package/test/ng/directive/ref.spec.js +575 -0
- package/test/ng/directive/repeat.spec.js +1675 -0
- package/test/ng/directive/script.spec.js +52 -0
- package/test/ng/directive/scrset.spec.js +67 -0
- package/test/ng/directive/select.spec.js +2541 -0
- package/test/ng/directive/show-hide.spec.js +253 -0
- package/test/ng/directive/src.spec.js +157 -0
- package/test/ng/directive/style.spec.js +178 -0
- package/test/ng/directive/switch.spec.js +647 -0
- package/test/ng/directive/validators.spec.js +717 -0
- package/test/ng/document.spec.js +52 -0
- package/test/ng/filter/filter.spec.js +714 -0
- package/test/ng/filter/filters.spec.js +35 -0
- package/test/ng/filter/limit-to.spec.js +251 -0
- package/test/ng/filter/order-by.spec.js +891 -0
- package/test/ng/filter.spec.js +149 -0
- package/test/ng/http-backend.spec.js +398 -0
- package/test/ng/http.spec.js +4071 -0
- package/test/ng/interpolate.spec.js +642 -0
- package/test/ng/interval.spec.js +343 -0
- package/test/ng/location.spec.js +3488 -0
- package/test/ng/on.spec.js +229 -0
- package/test/ng/parse.spec.js +4655 -0
- package/test/ng/prop.spec.js +805 -0
- package/test/ng/q.spec.js +2904 -0
- package/test/ng/root-element.spec.js +16 -0
- package/test/ng/sanitize-uri.spec.js +249 -0
- package/test/ng/sce.spec.js +660 -0
- package/test/ng/scope.spec.js +3442 -0
- package/test/ng/template-request.spec.js +236 -0
- package/test/ng/timeout.spec.js +351 -0
- package/test/ng/url-utils.spec.js +156 -0
- package/test/ng/utils.spec.js +144 -0
- package/test/original-test.html +21 -0
- package/test/public.spec.js +34 -0
- package/test/sanitize/bing-html.spec.js +36 -0
- package/test/server/express.js +158 -0
- package/test/test-utils.js +11 -0
- package/tsconfig.json +17 -0
- package/types/angular.d.ts +138 -0
- package/types/global.d.ts +9 -0
- package/types/index.d.ts +2357 -0
- package/types/jqlite.d.ts +558 -0
- package/vite.config.js +14 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { valueFn } from "./utils";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ! This is a private undocumented service !
|
|
5
|
+
*
|
|
6
|
+
* @name $$taskTrackerFactory
|
|
7
|
+
* @description
|
|
8
|
+
* A function to create `TaskTracker` instances.
|
|
9
|
+
*
|
|
10
|
+
* A `TaskTracker` can keep track of pending tasks (grouped by type) and can notify interested
|
|
11
|
+
* parties when all pending tasks (or tasks of a specific type) have been completed.
|
|
12
|
+
*
|
|
13
|
+
* @param {$log} log - A logger instance (such as `$log`). Used to log error during callback
|
|
14
|
+
* execution.
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
export function $$TaskTrackerFactoryProvider() {
|
|
19
|
+
// eslint-disable-next-line no-use-before-define
|
|
20
|
+
this.$get = valueFn((log) => new TaskTracker(log));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function TaskTracker(log) {
|
|
24
|
+
const self = this;
|
|
25
|
+
const taskCounts = {};
|
|
26
|
+
const taskCallbacks = [];
|
|
27
|
+
|
|
28
|
+
const ALL_TASKS_TYPE = (self.ALL_TASKS_TYPE = "$$all$$");
|
|
29
|
+
const DEFAULT_TASK_TYPE = (self.DEFAULT_TASK_TYPE = "$$default$$");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Execute the specified function and decrement the appropriate `taskCounts` counter.
|
|
33
|
+
* If the counter reaches 0, all corresponding `taskCallbacks` are executed.
|
|
34
|
+
*
|
|
35
|
+
* @param {Function} fn - The function to execute.
|
|
36
|
+
* @param {string=} [taskType=DEFAULT_TASK_TYPE] - The type of task that is being completed.
|
|
37
|
+
*/
|
|
38
|
+
self.completeTask = completeTask;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Increase the task count for the specified task type (or the default task type if non is
|
|
42
|
+
* specified).
|
|
43
|
+
*
|
|
44
|
+
* @param {string=} [taskType=DEFAULT_TASK_TYPE] - The type of task whose count will be increased.
|
|
45
|
+
*/
|
|
46
|
+
self.incTaskCount = incTaskCount;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Execute the specified callback when all pending tasks have been completed.
|
|
50
|
+
*
|
|
51
|
+
* If there are no pending tasks, the callback is executed immediately. You can optionally limit
|
|
52
|
+
* the tasks that will be waited for to a specific type, by passing a `taskType`.
|
|
53
|
+
*
|
|
54
|
+
* @param {function} callback - The function to call when there are no pending tasks.
|
|
55
|
+
* @param {string=} [taskType=ALL_TASKS_TYPE] - The type of tasks that will be waited for.
|
|
56
|
+
*/
|
|
57
|
+
self.notifyWhenNoPendingTasks = notifyWhenNoPendingTasks;
|
|
58
|
+
|
|
59
|
+
function completeTask(fn, taskType) {
|
|
60
|
+
taskType = taskType || DEFAULT_TASK_TYPE;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
fn();
|
|
64
|
+
} finally {
|
|
65
|
+
decTaskCount(taskType);
|
|
66
|
+
|
|
67
|
+
const countForType = taskCounts[taskType];
|
|
68
|
+
const countForAll = taskCounts[ALL_TASKS_TYPE];
|
|
69
|
+
|
|
70
|
+
// If at least one of the queues (`ALL_TASKS_TYPE` or `taskType`) is empty, run callbacks.
|
|
71
|
+
if (!countForAll || !countForType) {
|
|
72
|
+
const getNextCallback = !countForAll
|
|
73
|
+
? getLastCallback
|
|
74
|
+
: getLastCallbackForType;
|
|
75
|
+
let nextCb;
|
|
76
|
+
|
|
77
|
+
while ((nextCb = getNextCallback(taskType))) {
|
|
78
|
+
try {
|
|
79
|
+
nextCb();
|
|
80
|
+
} catch (e) {
|
|
81
|
+
log.error(e);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function decTaskCount(taskType) {
|
|
89
|
+
taskType = taskType || DEFAULT_TASK_TYPE;
|
|
90
|
+
if (taskCounts[taskType]) {
|
|
91
|
+
taskCounts[taskType]--;
|
|
92
|
+
taskCounts[ALL_TASKS_TYPE]--;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getLastCallback() {
|
|
97
|
+
const cbInfo = taskCallbacks.pop();
|
|
98
|
+
return cbInfo && cbInfo.cb;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getLastCallbackForType(taskType) {
|
|
102
|
+
for (let i = taskCallbacks.length - 1; i >= 0; --i) {
|
|
103
|
+
const cbInfo = taskCallbacks[i];
|
|
104
|
+
if (cbInfo.type === taskType) {
|
|
105
|
+
taskCallbacks.splice(i, 1);
|
|
106
|
+
return cbInfo.cb;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function incTaskCount(taskType) {
|
|
112
|
+
taskType = taskType || DEFAULT_TASK_TYPE;
|
|
113
|
+
taskCounts[taskType] = (taskCounts[taskType] || 0) + 1;
|
|
114
|
+
taskCounts[ALL_TASKS_TYPE] = (taskCounts[ALL_TASKS_TYPE] || 0) + 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function notifyWhenNoPendingTasks(callback, taskType) {
|
|
118
|
+
taskType = taskType || ALL_TASKS_TYPE;
|
|
119
|
+
if (!taskCounts[taskType]) {
|
|
120
|
+
callback();
|
|
121
|
+
} else {
|
|
122
|
+
taskCallbacks.push({ type: taskType, cb: callback });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { markQExceptionHandled } from "./q";
|
|
2
|
+
import { isDefined, isFunction, minErr, sliceArgs } from "./utils";
|
|
3
|
+
|
|
4
|
+
const $timeoutMinErr = minErr("$timeout");
|
|
5
|
+
|
|
6
|
+
export function $timeout($rootScope, $browser, $q, $$q, $exceptionHandler) {
|
|
7
|
+
const deferreds = {};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @ngdoc service
|
|
11
|
+
* @name $timeout
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* AngularJS's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
|
|
15
|
+
* block and delegates any exceptions to
|
|
16
|
+
* {@link ng.$exceptionHandler $exceptionHandler} service.
|
|
17
|
+
*
|
|
18
|
+
* The return value of calling `$timeout` is a promise, which will be resolved when
|
|
19
|
+
* the delay has passed and the timeout function, if provided, is executed.
|
|
20
|
+
*
|
|
21
|
+
* To cancel a timeout request, call `$timeout.cancel(promise)`.
|
|
22
|
+
*
|
|
23
|
+
* In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
|
|
24
|
+
* synchronously flush the queue of deferred functions.
|
|
25
|
+
*
|
|
26
|
+
* If you only want a promise that will be resolved after some specified delay
|
|
27
|
+
* then you can call `$timeout` without the `fn` function.
|
|
28
|
+
*
|
|
29
|
+
* @param {function()=} fn A function, whose execution should be delayed.
|
|
30
|
+
* @param {number=} [delay=0] Delay in milliseconds.
|
|
31
|
+
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
|
32
|
+
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
|
33
|
+
* @param {...*=} Pass additional parameters to the executed function.
|
|
34
|
+
* @returns {Promise} Promise that will be resolved when the timeout is reached. The promise
|
|
35
|
+
* will be resolved with the return value of the `fn` function.
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
function timeout(fn, delay, invokeApply) {
|
|
39
|
+
if (!isFunction(fn)) {
|
|
40
|
+
invokeApply = delay;
|
|
41
|
+
delay = fn;
|
|
42
|
+
fn = () => {};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const args = sliceArgs(arguments, 3);
|
|
46
|
+
const skipApply = isDefined(invokeApply) && !invokeApply;
|
|
47
|
+
const deferred = (skipApply ? $$q : $q).defer();
|
|
48
|
+
const { promise } = deferred;
|
|
49
|
+
let timeoutId;
|
|
50
|
+
|
|
51
|
+
timeoutId = $browser.defer(
|
|
52
|
+
() => {
|
|
53
|
+
try {
|
|
54
|
+
deferred.resolve(fn.apply(null, args));
|
|
55
|
+
} catch (e) {
|
|
56
|
+
deferred.reject(e);
|
|
57
|
+
$exceptionHandler(e);
|
|
58
|
+
} finally {
|
|
59
|
+
delete deferreds[promise.$$timeoutId];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!skipApply) $rootScope.$apply();
|
|
63
|
+
},
|
|
64
|
+
delay,
|
|
65
|
+
"$timeout",
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
promise.$$timeoutId = timeoutId;
|
|
69
|
+
deferreds[timeoutId] = deferred;
|
|
70
|
+
|
|
71
|
+
return promise;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @ngdoc method
|
|
76
|
+
* @name $timeout#cancel
|
|
77
|
+
*
|
|
78
|
+
* @description
|
|
79
|
+
* Cancels a task associated with the `promise`. As a result of this, the promise will be
|
|
80
|
+
* resolved with a rejection.
|
|
81
|
+
*
|
|
82
|
+
* @param {Promise=} promise Promise returned by the `$timeout` function.
|
|
83
|
+
* @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
|
|
84
|
+
* canceled.
|
|
85
|
+
*/
|
|
86
|
+
timeout.cancel = function (promise) {
|
|
87
|
+
if (!promise) return false;
|
|
88
|
+
|
|
89
|
+
if (!Object.prototype.hasOwnProperty.call(promise, "$$timeoutId")) {
|
|
90
|
+
throw $timeoutMinErr(
|
|
91
|
+
"badprom",
|
|
92
|
+
"`$timeout.cancel()` called with a promise that was not generated by `$timeout()`.",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!Object.prototype.hasOwnProperty.call(deferreds, promise.$$timeoutId))
|
|
97
|
+
return false;
|
|
98
|
+
const id = promise.$$timeoutId;
|
|
99
|
+
const deferred = deferreds[id];
|
|
100
|
+
|
|
101
|
+
// Timeout cancels should not report an unhandled promise.
|
|
102
|
+
markQExceptionHandled(deferred.promise);
|
|
103
|
+
deferred.reject("canceled");
|
|
104
|
+
delete deferreds[id];
|
|
105
|
+
|
|
106
|
+
return $browser.defer.cancel(id);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return timeout;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function $TimeoutProvider() {
|
|
113
|
+
this.$get = [
|
|
114
|
+
"$rootScope",
|
|
115
|
+
"$browser",
|
|
116
|
+
"$q",
|
|
117
|
+
"$$q",
|
|
118
|
+
"$exceptionHandler",
|
|
119
|
+
$timeout,
|
|
120
|
+
];
|
|
121
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/* eslint-disable no-use-before-define */
|
|
2
|
+
|
|
3
|
+
import { isString } from "./utils";
|
|
4
|
+
|
|
5
|
+
// service.
|
|
6
|
+
const urlParsingNode = window.document.createElement("a");
|
|
7
|
+
const originUrl = urlResolve(window.location.href);
|
|
8
|
+
let baseUrlParsingNode;
|
|
9
|
+
|
|
10
|
+
urlParsingNode.href = "http://[::1]";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Implementation Notes for non-IE browsers
|
|
15
|
+
* ----------------------------------------
|
|
16
|
+
* Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,
|
|
17
|
+
* results both in the normalizing and parsing of the URL. Normalizing means that a relative
|
|
18
|
+
* URL will be resolved into an absolute URL in the context of the application document.
|
|
19
|
+
* Parsing means that the anchor node's host, hostname, protocol, port, pathname and related
|
|
20
|
+
* properties are all populated to reflect the normalized URL. This approach has wide
|
|
21
|
+
* compatibility - Safari 1+, Mozilla 1+ etc. See
|
|
22
|
+
* http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
|
|
23
|
+
*
|
|
24
|
+
* Implementation Notes for IE
|
|
25
|
+
* ---------------------------
|
|
26
|
+
* IE <= 10 normalizes the URL when assigned to the anchor node similar to the other
|
|
27
|
+
* browsers. However, the parsed components will not be set if the URL assigned did not specify
|
|
28
|
+
* them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
|
|
29
|
+
* work around that by performing the parsing in a 2nd step by taking a previously normalized
|
|
30
|
+
* URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the
|
|
31
|
+
* properties such as protocol, hostname, port, etc.
|
|
32
|
+
*
|
|
33
|
+
* References:
|
|
34
|
+
* http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement
|
|
35
|
+
* http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
|
|
36
|
+
* http://url.spec.whatwg.org/#urlutils
|
|
37
|
+
* https://github.com/angular/angular.js/pull/2902
|
|
38
|
+
* http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
|
|
39
|
+
*
|
|
40
|
+
* @kind function
|
|
41
|
+
* @param {string|object} url The URL to be parsed. If `url` is not a string, it will be returned
|
|
42
|
+
* unchanged.
|
|
43
|
+
* @description Normalizes and parses a URL.
|
|
44
|
+
* @returns {object} Returns the normalized URL as a dictionary.
|
|
45
|
+
*
|
|
46
|
+
* | member name | Description |
|
|
47
|
+
* |---------------|------------------------------------------------------------------------|
|
|
48
|
+
* | href | A normalized version of the provided URL if it was not an absolute URL |
|
|
49
|
+
* | protocol | The protocol without the trailing colon |
|
|
50
|
+
* | host | The host and port (if the port is non-default) of the normalizedUrl |
|
|
51
|
+
* | search | The search params, minus the question mark |
|
|
52
|
+
* | hash | The hash string, minus the hash symbol |
|
|
53
|
+
* | hostname | The hostname |
|
|
54
|
+
* | port | The port, without ":" |
|
|
55
|
+
* | pathname | The pathname, beginning with "/" |
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
export function urlResolve(url) {
|
|
59
|
+
if (!isString(url)) return url;
|
|
60
|
+
|
|
61
|
+
const href = url;
|
|
62
|
+
|
|
63
|
+
urlParsingNode.setAttribute("href", href);
|
|
64
|
+
|
|
65
|
+
let { hostname } = urlParsingNode;
|
|
66
|
+
// Support: IE 9-11 only, Edge 16-17 only (fixed in 18 Preview)
|
|
67
|
+
// IE/Edge don't wrap IPv6 addresses' hostnames in square brackets
|
|
68
|
+
// when parsed out of an anchor element.
|
|
69
|
+
const ipv6InBrackets = urlParsingNode.hostname === "[::1]";
|
|
70
|
+
if (!ipv6InBrackets && hostname.indexOf(":") > -1) {
|
|
71
|
+
hostname = `[${hostname}]`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
href: urlParsingNode.href,
|
|
76
|
+
protocol: urlParsingNode.protocol
|
|
77
|
+
? urlParsingNode.protocol.replace(/:$/, "")
|
|
78
|
+
: "",
|
|
79
|
+
host: urlParsingNode.host,
|
|
80
|
+
search: urlParsingNode.search
|
|
81
|
+
? urlParsingNode.search.replace(/^\?/, "")
|
|
82
|
+
: "",
|
|
83
|
+
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, "") : "",
|
|
84
|
+
hostname,
|
|
85
|
+
port: urlParsingNode.port,
|
|
86
|
+
pathname:
|
|
87
|
+
urlParsingNode.pathname.charAt(0) === "/"
|
|
88
|
+
? urlParsingNode.pathname
|
|
89
|
+
: `/${urlParsingNode.pathname}`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Parse a request URL and determine whether this is a same-origin request as the application
|
|
95
|
+
* document.
|
|
96
|
+
*
|
|
97
|
+
* @param {string|object} requestUrl The url of the request as a string that will be resolved
|
|
98
|
+
* or a parsed URL object.
|
|
99
|
+
* @returns {boolean} Whether the request is for the same origin as the application document.
|
|
100
|
+
*/
|
|
101
|
+
export function urlIsSameOrigin(requestUrl) {
|
|
102
|
+
return urlsAreSameOrigin(requestUrl, originUrl);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parse a request URL and determine whether it is same-origin as the current document base URL.
|
|
107
|
+
*
|
|
108
|
+
* Note: The base URL is usually the same as the document location (`location.href`) but can
|
|
109
|
+
* be overriden by using the `<base>` tag.
|
|
110
|
+
*
|
|
111
|
+
* @param {string|object} requestUrl The url of the request as a string that will be resolved
|
|
112
|
+
* or a parsed URL object.
|
|
113
|
+
* @returns {boolean} Whether the URL is same-origin as the document base URL.
|
|
114
|
+
*/
|
|
115
|
+
export function urlIsSameOriginAsBaseUrl(requestUrl) {
|
|
116
|
+
return urlsAreSameOrigin(requestUrl, getBaseUrl());
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create a function that can check a URL's origin against a list of allowed/trusted origins.
|
|
121
|
+
* The current location's origin is implicitly trusted.
|
|
122
|
+
*
|
|
123
|
+
* @param {string[]} trustedOriginUrls - A list of URLs (strings), whose origins are trusted.
|
|
124
|
+
*
|
|
125
|
+
* @returns {Function} - A function that receives a URL (string or parsed URL object) and returns
|
|
126
|
+
* whether it is of an allowed origin.
|
|
127
|
+
*/
|
|
128
|
+
export function urlIsAllowedOriginFactory(trustedOriginUrls) {
|
|
129
|
+
const parsedAllowedOriginUrls = [originUrl].concat(
|
|
130
|
+
trustedOriginUrls.map(urlResolve),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check whether the specified URL (string or parsed URL object) has an origin that is allowed
|
|
135
|
+
* based on a list of trusted-origin URLs. The current location's origin is implicitly
|
|
136
|
+
* trusted.
|
|
137
|
+
*
|
|
138
|
+
* @param {string|Object} requestUrl - The URL to be checked (provided as a string that will be
|
|
139
|
+
* resolved or a parsed URL object).
|
|
140
|
+
*
|
|
141
|
+
* @returns {boolean} - Whether the specified URL is of an allowed origin.
|
|
142
|
+
*/
|
|
143
|
+
return function urlIsAllowedOrigin(requestUrl) {
|
|
144
|
+
const parsedUrl = urlResolve(requestUrl);
|
|
145
|
+
return parsedAllowedOriginUrls.some(
|
|
146
|
+
urlsAreSameOrigin.bind(null, parsedUrl),
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Determine if two URLs share the same origin.
|
|
153
|
+
*
|
|
154
|
+
* @param {string|Object} url1 - First URL to compare as a string or a normalized URL in the form of
|
|
155
|
+
* a dictionary object returned by `urlResolve()`.
|
|
156
|
+
* @param {string|object} url2 - Second URL to compare as a string or a normalized URL in the form
|
|
157
|
+
* of a dictionary object returned by `urlResolve()`.
|
|
158
|
+
*
|
|
159
|
+
* @returns {boolean} - True if both URLs have the same origin, and false otherwise.
|
|
160
|
+
*/
|
|
161
|
+
export function urlsAreSameOrigin(url1, url2) {
|
|
162
|
+
url1 = urlResolve(url1);
|
|
163
|
+
url2 = urlResolve(url2);
|
|
164
|
+
|
|
165
|
+
return url1.protocol === url2.protocol && url1.host === url2.host;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Returns the current document base URL.
|
|
170
|
+
* @returns {string}
|
|
171
|
+
*/
|
|
172
|
+
export function getBaseUrl() {
|
|
173
|
+
if (window.document.baseURI) {
|
|
174
|
+
return window.document.baseURI;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// `document.baseURI` is available everywhere except IE
|
|
178
|
+
if (!baseUrlParsingNode) {
|
|
179
|
+
baseUrlParsingNode = window.document.createElement("a");
|
|
180
|
+
baseUrlParsingNode.href = ".";
|
|
181
|
+
|
|
182
|
+
// Work-around for IE bug described in Implementation Notes. The fix in `urlResolve()` is not
|
|
183
|
+
// suitable here because we need to track changes to the base URL.
|
|
184
|
+
baseUrlParsingNode = baseUrlParsingNode.cloneNode(false);
|
|
185
|
+
}
|
|
186
|
+
return baseUrlParsingNode.href;
|
|
187
|
+
}
|