@angular-wave/angular.ts 0.3.1 → 0.4.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/.github/workflows/ci.yml +57 -0
- package/README.md +1 -1
- package/dist/angular-ts.esm.js +2 -2
- package/dist/angular-ts.umd.js +2 -2
- package/package.json +1 -1
- package/src/core/compile/attributes.js +1 -1
- package/src/core/compile/compile.js +1 -1
- package/src/core/compile/compile.test.js +1 -1
- package/src/core/exception-handler.js +1 -5
- package/src/core/interpolate/interpolate.js +33 -26
- package/src/core/interval/interval-factory.js +6 -22
- package/src/core/interval/interval.spec.js +0 -25
- package/src/core/q/q.js +0 -27
- package/src/core/q/q.spec.js +0 -44
- package/src/core/scope/scope.js +35 -42
- package/src/core/scope/scope.spec.js +71 -13
- package/src/core/timeout/timeout.js +2 -6
- package/src/directive/attrs/attrs.js +1 -1
- package/src/directive/input/input.spec.js +0 -1
- package/src/directive/observe/observe.html +18 -0
- package/src/directive/observe/observe.js +37 -0
- package/src/directive/observe/observe.spec.js +92 -0
- package/src/directive/observe/observe.test.js +9 -0
- package/src/directive/observe/test.html +197 -0
- package/src/public.js +7 -6
- package/src/router/state/state-service.js +3 -3
- package/src/router/view-scroll.js +13 -8
- package/src/services/log.js +0 -6
- package/types/core/compile/attributes.d.ts +3 -3
- package/types/core/compile/compile.d.ts +1 -1
- package/types/core/exception-handler.d.ts +2 -2
- package/types/core/interpolate/interpolate.d.ts +7 -4
- package/types/core/interval/interval-factory.d.ts +1 -1
- package/types/core/q/q.d.ts +0 -5
- package/types/core/scope/scope.d.ts +11 -2
- package/types/core/timeout/timeout.d.ts +2 -2
- package/types/directive/observe/observe.d.ts +4 -0
- package/types/router/state/state-service.d.ts +1 -1
- package/types/router/view-scroll.d.ts +3 -3
- package/types/services/log.d.ts +0 -5
- package/.github/workflows/lint.yml +0 -19
- package/.github/workflows/playwright.yml +0 -27
- package/.github/workflows/types.yml +0 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $$asyncQueue } from "./scope";
|
|
1
|
+
import { $$asyncQueue, Scope } from "./scope";
|
|
2
2
|
import { extend, sliceArgs } from "../../shared/utils";
|
|
3
3
|
import { Angular } from "../../loader";
|
|
4
4
|
import { createInjector } from "../di/injector";
|
|
@@ -8,6 +8,7 @@ describe("Scope", function () {
|
|
|
8
8
|
let $parse;
|
|
9
9
|
let $browser;
|
|
10
10
|
let logs;
|
|
11
|
+
let scope;
|
|
11
12
|
|
|
12
13
|
beforeEach(() => {
|
|
13
14
|
logs = [];
|
|
@@ -27,6 +28,21 @@ describe("Scope", function () {
|
|
|
27
28
|
$browser = injector.get("$browser");
|
|
28
29
|
|
|
29
30
|
$rootScope = injector.get("$rootScope");
|
|
31
|
+
scope = $rootScope;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("class", () => {
|
|
35
|
+
it("can be constructed as a class", () => {
|
|
36
|
+
const scope = new Scope();
|
|
37
|
+
expect(scope).toBeDefined();
|
|
38
|
+
expect(scope.isRoot).toBeFalse();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("can be constructed as a root scope", () => {
|
|
42
|
+
const scope = new Scope(true);
|
|
43
|
+
expect(scope).toBeDefined();
|
|
44
|
+
expect(scope.isRoot).toBeTrue();
|
|
45
|
+
});
|
|
30
46
|
});
|
|
31
47
|
|
|
32
48
|
describe("inheritance", () => {
|
|
@@ -49,7 +65,7 @@ describe("Scope", function () {
|
|
|
49
65
|
const child = $rootScope.$new();
|
|
50
66
|
child.aValue = [1, 2, 3];
|
|
51
67
|
|
|
52
|
-
expect(
|
|
68
|
+
expect($rootScope.aValue).toBeUndefined();
|
|
53
69
|
});
|
|
54
70
|
|
|
55
71
|
it("inherits the parents properties whenever they are defined", () => {
|
|
@@ -91,6 +107,7 @@ describe("Scope", function () {
|
|
|
91
107
|
|
|
92
108
|
expect(child.aValue).toEqual([1, 2, 3, 4]);
|
|
93
109
|
expect($rootScope.aValue).toEqual([1, 2, 3, 4]);
|
|
110
|
+
expect(child.aValue).toEqual($rootScope.aValue);
|
|
94
111
|
});
|
|
95
112
|
});
|
|
96
113
|
|
|
@@ -122,6 +139,7 @@ describe("Scope", function () {
|
|
|
122
139
|
$rootScope.a = 123;
|
|
123
140
|
expect(isolated.a).toBeUndefined();
|
|
124
141
|
expect(trans.a).toEqual(123);
|
|
142
|
+
expect(trans.$root).toBe($rootScope);
|
|
125
143
|
expect(trans.$parent).toBe(isolated);
|
|
126
144
|
});
|
|
127
145
|
});
|
|
@@ -171,13 +189,53 @@ describe("Scope", function () {
|
|
|
171
189
|
expect($rootScope.$eval("this")).toEqual($rootScope);
|
|
172
190
|
});
|
|
173
191
|
|
|
174
|
-
it("should be able to access a
|
|
192
|
+
it("should be able to access a constant variable named 'this'", () => {
|
|
175
193
|
$rootScope.this = 42;
|
|
176
194
|
expect($rootScope.$eval("this['this']")).toBe(42);
|
|
177
195
|
});
|
|
178
196
|
});
|
|
179
197
|
|
|
180
198
|
describe("$watch/$digest", () => {
|
|
199
|
+
it("calls the listener function of a watch on first $digest", function () {
|
|
200
|
+
var watchFn = function () {
|
|
201
|
+
return "wat";
|
|
202
|
+
};
|
|
203
|
+
var listenerFn = jasmine.createSpy();
|
|
204
|
+
$rootScope.$watch(watchFn, listenerFn);
|
|
205
|
+
$rootScope.$digest();
|
|
206
|
+
expect(listenerFn).toHaveBeenCalled();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("calls the watch function with the scope as the argument", function () {
|
|
210
|
+
var watchFn = jasmine.createSpy();
|
|
211
|
+
var listenerFn = function () {};
|
|
212
|
+
$rootScope.$watch(watchFn, listenerFn);
|
|
213
|
+
$rootScope.$digest();
|
|
214
|
+
expect(watchFn).toHaveBeenCalledWith($rootScope);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("calls the listener function when the watched value changes", function () {
|
|
218
|
+
scope.someValue = "a";
|
|
219
|
+
scope.counter = 0;
|
|
220
|
+
scope.$watch(
|
|
221
|
+
function (scope) {
|
|
222
|
+
return scope.someValue;
|
|
223
|
+
},
|
|
224
|
+
function (newValue, oldValue, scope) {
|
|
225
|
+
scope.counter++;
|
|
226
|
+
},
|
|
227
|
+
);
|
|
228
|
+
expect(scope.counter).toBe(0);
|
|
229
|
+
scope.$digest();
|
|
230
|
+
expect(scope.counter).toBe(1);
|
|
231
|
+
scope.$digest();
|
|
232
|
+
expect(scope.counter).toBe(1);
|
|
233
|
+
scope.someValue = "b";
|
|
234
|
+
expect(scope.counter).toBe(1);
|
|
235
|
+
scope.$digest();
|
|
236
|
+
expect(scope.counter).toBe(2);
|
|
237
|
+
});
|
|
238
|
+
|
|
181
239
|
it("should watch and fire on simple property change", () => {
|
|
182
240
|
const spy = jasmine.createSpy();
|
|
183
241
|
$rootScope.$watch("name", spy);
|
|
@@ -2870,13 +2928,13 @@ describe("Scope", function () {
|
|
|
2870
2928
|
const remove1 = $rootScope.$on("abc", () => {});
|
|
2871
2929
|
$rootScope.$on("abc", () => {});
|
|
2872
2930
|
|
|
2873
|
-
expect($rootScope.$$listeners.abc.length).toBe(2);
|
|
2874
|
-
expect(0 in $rootScope.$$listeners.abc).toBe(true);
|
|
2931
|
+
expect($rootScope.$$listeners.get("abc").length).toBe(2);
|
|
2932
|
+
expect(0 in $rootScope.$$listeners.get("abc")).toBe(true);
|
|
2875
2933
|
|
|
2876
2934
|
remove1();
|
|
2877
2935
|
|
|
2878
|
-
expect($rootScope.$$listeners.abc.length).toBe(2);
|
|
2879
|
-
expect(0 in $rootScope.$$listeners.abc).toBe(false);
|
|
2936
|
+
expect($rootScope.$$listeners.get("abc").length).toBe(2);
|
|
2937
|
+
expect(0 in $rootScope.$$listeners.get("abc")).toBe(false);
|
|
2880
2938
|
});
|
|
2881
2939
|
|
|
2882
2940
|
it("should call next listener after removing the current listener via its own handler", () => {
|
|
@@ -3097,14 +3155,14 @@ describe("Scope", function () {
|
|
|
3097
3155
|
|
|
3098
3156
|
spy1.and.callFake(remove1);
|
|
3099
3157
|
|
|
3100
|
-
expect(child.$$listeners.evt.length).toBe(3);
|
|
3158
|
+
expect(child.$$listeners.get("evt").length).toBe(3);
|
|
3101
3159
|
|
|
3102
3160
|
// should call all listeners and remove 1st
|
|
3103
3161
|
child.$emit("evt");
|
|
3104
3162
|
expect(spy1).toHaveBeenCalled();
|
|
3105
3163
|
expect(spy2).toHaveBeenCalled();
|
|
3106
3164
|
expect(spy3).toHaveBeenCalled();
|
|
3107
|
-
expect(child.$$listeners.evt.length).toBe(3); // cleanup will happen on next $emit
|
|
3165
|
+
expect(child.$$listeners.get("evt").length).toBe(3); // cleanup will happen on next $emit
|
|
3108
3166
|
|
|
3109
3167
|
spy1.calls.reset();
|
|
3110
3168
|
spy2.calls.reset();
|
|
@@ -3116,7 +3174,7 @@ describe("Scope", function () {
|
|
|
3116
3174
|
expect(spy1).not.toHaveBeenCalled();
|
|
3117
3175
|
expect(spy2).toHaveBeenCalled();
|
|
3118
3176
|
expect(spy3).not.toHaveBeenCalled();
|
|
3119
|
-
expect(child.$$listeners.evt.length).toBe(1);
|
|
3177
|
+
expect(child.$$listeners.get("evt").length).toBe(1);
|
|
3120
3178
|
});
|
|
3121
3179
|
|
|
3122
3180
|
it("should allow removing event listener inside a listener on $broadcast", () => {
|
|
@@ -3130,14 +3188,14 @@ describe("Scope", function () {
|
|
|
3130
3188
|
|
|
3131
3189
|
spy1.and.callFake(remove1);
|
|
3132
3190
|
|
|
3133
|
-
expect(child.$$listeners.evt.length).toBe(3);
|
|
3191
|
+
expect(child.$$listeners.get("evt").length).toBe(3);
|
|
3134
3192
|
|
|
3135
3193
|
// should call all listeners and remove 1st
|
|
3136
3194
|
child.$broadcast("evt");
|
|
3137
3195
|
expect(spy1).toHaveBeenCalled();
|
|
3138
3196
|
expect(spy2).toHaveBeenCalled();
|
|
3139
3197
|
expect(spy3).toHaveBeenCalled();
|
|
3140
|
-
expect(child.$$listeners.evt.length).toBe(3); // cleanup will happen on next $broadcast
|
|
3198
|
+
expect(child.$$listeners.get("evt").length).toBe(3); // cleanup will happen on next $broadcast
|
|
3141
3199
|
|
|
3142
3200
|
spy1.calls.reset();
|
|
3143
3201
|
spy2.calls.reset();
|
|
@@ -3149,7 +3207,7 @@ describe("Scope", function () {
|
|
|
3149
3207
|
expect(spy1).not.toHaveBeenCalled();
|
|
3150
3208
|
expect(spy2).toHaveBeenCalled();
|
|
3151
3209
|
expect(spy3).not.toHaveBeenCalled();
|
|
3152
|
-
expect(child.$$listeners.evt.length).toBe(1);
|
|
3210
|
+
expect(child.$$listeners.get("evt").length).toBe(1);
|
|
3153
3211
|
});
|
|
3154
3212
|
|
|
3155
3213
|
describe("event object", () => {
|
|
@@ -8,18 +8,16 @@ export class TimeoutProvider {
|
|
|
8
8
|
"$rootScope",
|
|
9
9
|
"$browser",
|
|
10
10
|
"$q",
|
|
11
|
-
"$$q",
|
|
12
11
|
"$exceptionHandler",
|
|
13
12
|
/**
|
|
14
13
|
*
|
|
15
14
|
* @param {import('../scope/scope').Scope} $rootScope
|
|
16
15
|
* @param {import('../../services/browser').Browser} $browser
|
|
17
16
|
* @param {*} $q
|
|
18
|
-
* @param {*} $$q
|
|
19
17
|
* @param {import('../exception-handler').ErrorHandler} $exceptionHandler
|
|
20
18
|
* @returns
|
|
21
19
|
*/
|
|
22
|
-
($rootScope, $browser, $q,
|
|
20
|
+
($rootScope, $browser, $q, $exceptionHandler) => {
|
|
23
21
|
const deferreds = {};
|
|
24
22
|
|
|
25
23
|
/**
|
|
@@ -38,8 +36,6 @@ export class TimeoutProvider {
|
|
|
38
36
|
*
|
|
39
37
|
* @param {function()=} fn A function, whose execution should be delayed.
|
|
40
38
|
* @param {number=} [delay=0] Delay in milliseconds.
|
|
41
|
-
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
|
42
|
-
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
|
43
39
|
* @returns {import("../q/q").QPromise<any>} Promise that will be resolved when the timeout is reached. The promise
|
|
44
40
|
* will be resolved with the return value of the `fn` function.
|
|
45
41
|
*
|
|
@@ -47,7 +43,7 @@ export class TimeoutProvider {
|
|
|
47
43
|
function timeout(fn, delay, invokeApply = true) {
|
|
48
44
|
const args = sliceArgs(arguments, 3);
|
|
49
45
|
const skipApply = isDefined(invokeApply) && !invokeApply;
|
|
50
|
-
const deferred =
|
|
46
|
+
const deferred = $q.defer();
|
|
51
47
|
const { promise } = deferred;
|
|
52
48
|
let timeoutId;
|
|
53
49
|
|
|
@@ -11,7 +11,7 @@ Object.entries(BOOLEAN_ATTR).forEach(([attrName, propName]) => {
|
|
|
11
11
|
// binding to multiple is not supported
|
|
12
12
|
if (propName === "multiple") return;
|
|
13
13
|
|
|
14
|
-
function defaultLinkFn(scope,
|
|
14
|
+
function defaultLinkFn(scope, _element, attr) {
|
|
15
15
|
scope.$watch(attr[normalized], (value) => {
|
|
16
16
|
attr.$set(attrName, !!value);
|
|
17
17
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Angular } from "../../loader";
|
|
2
|
-
import { createInjector } from "../../core/di/injector";
|
|
3
2
|
import { dealoc, JQLite } from "../../shared/jqlite/jqlite";
|
|
4
3
|
import { EMAIL_REGEXP, ISO_DATE_REGEXP, URL_REGEXP } from "./input";
|
|
5
4
|
import { forEach } from "../../shared/utils";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>AngularTS Test Runner</title>
|
|
6
|
+
|
|
7
|
+
<link rel="shortcut icon" type="image/png" href="/images/favicon.ico" />
|
|
8
|
+
<link rel="stylesheet" href="/jasmine/jasmine-5.1.2/jasmine.css" />
|
|
9
|
+
<script src="/jasmine/jasmine-5.1.2/jasmine.js"></script>
|
|
10
|
+
<script src="/jasmine/jasmine-5.1.2/jasmine-html.js"></script>
|
|
11
|
+
<script src="/jasmine/jasmine-5.1.2/boot0.js"></script>
|
|
12
|
+
<script src="/jasmine/jasmine-5.1.2/boot1.js"></script>
|
|
13
|
+
<script type="module" src="/src/directive/observe/observe.spec.js"></script>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<div id="dummy"></div>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @returns {import("../../types").Directive}
|
|
3
|
+
*/
|
|
4
|
+
export function ngObserveDirective() {
|
|
5
|
+
return {
|
|
6
|
+
restrict: "A",
|
|
7
|
+
link: (scope, element, attrs) => {
|
|
8
|
+
const targetElement = element[0];
|
|
9
|
+
const prop = targetElement.dataset["update"];
|
|
10
|
+
const source = attrs["ngObserve"];
|
|
11
|
+
|
|
12
|
+
if (!scope[prop]) {
|
|
13
|
+
scope[prop] = targetElement.getAttribute(source);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const observer = new MutationObserver((mutations) => {
|
|
17
|
+
const mutation = mutations[0];
|
|
18
|
+
const newValue = /** @type {HTMLElement} */ (
|
|
19
|
+
mutation.target
|
|
20
|
+
).getAttribute(source);
|
|
21
|
+
if (scope[prop] !== newValue) {
|
|
22
|
+
scope[prop] = newValue;
|
|
23
|
+
scope.$digest();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
observer.observe(targetElement, {
|
|
28
|
+
attributes: true,
|
|
29
|
+
attributeFilter: [source],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
scope.$on("$destroy", () => {
|
|
33
|
+
observer.disconnect();
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Angular } from "../../loader";
|
|
2
|
+
import { JQLite } from "../../shared/jqlite/jqlite";
|
|
3
|
+
|
|
4
|
+
describe("observe", () => {
|
|
5
|
+
let $compile, $scope, $rootScope, element, observerSpy;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
window.angular = new Angular();
|
|
9
|
+
angular.module("myModule", ["ng"]);
|
|
10
|
+
angular
|
|
11
|
+
.bootstrap(document.getElementById("dummy"), ["myModule"])
|
|
12
|
+
.invoke((_$compile_, _$rootScope_) => {
|
|
13
|
+
$compile = _$compile_;
|
|
14
|
+
$rootScope = _$rootScope_;
|
|
15
|
+
$scope = $rootScope.$new();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
observerSpy = jasmine.createSpyObj("MutationObserver", [
|
|
19
|
+
"observe",
|
|
20
|
+
"disconnect",
|
|
21
|
+
]);
|
|
22
|
+
spyOn(window, "MutationObserver").and.returnValue(observerSpy); // Replace with a spy
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function createDirective(attributeValue, updateProp) {
|
|
26
|
+
const template = `<div ng-observe="${attributeValue}" data-update="${updateProp}"></div>`;
|
|
27
|
+
element = $compile(template)($scope);
|
|
28
|
+
$scope.$digest();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
it("should set the scope property to the attribute value before any changes", () => {
|
|
32
|
+
const scope = $rootScope.$new();
|
|
33
|
+
const element = JQLite(
|
|
34
|
+
'<div data-update="testProp" ng-observe="sourceAttr"></div>',
|
|
35
|
+
);
|
|
36
|
+
element.attr("sourceAttr", "initialValue");
|
|
37
|
+
$compile(element)(scope);
|
|
38
|
+
|
|
39
|
+
expect(scope.testProp).toBeDefined();
|
|
40
|
+
expect(scope.testProp).toEqual("initialValue");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should observe attribute changes and update the scope property", () => {
|
|
44
|
+
$scope.myProp = "";
|
|
45
|
+
createDirective("test-attribute", "myProp");
|
|
46
|
+
spyOn($scope, "$digest").and.callThrough();
|
|
47
|
+
|
|
48
|
+
const mutationObserverCallback =
|
|
49
|
+
MutationObserver.calls.mostRecent().args[0];
|
|
50
|
+
const mutationRecord = {
|
|
51
|
+
target: element[0],
|
|
52
|
+
attributeName: "test-attribute",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
element.attr("test-attribute", "newValue");
|
|
56
|
+
element[0].setAttribute("test-attribute", "newValue");
|
|
57
|
+
|
|
58
|
+
mutationObserverCallback([mutationRecord]);
|
|
59
|
+
|
|
60
|
+
expect($scope.myProp).toBe("newValue");
|
|
61
|
+
expect($scope.$digest).toHaveBeenCalled();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should not trigger digest cycle if the attribute value is unchanged", () => {
|
|
65
|
+
$scope.myProp = "existingValue";
|
|
66
|
+
createDirective("test-attribute", "myProp");
|
|
67
|
+
|
|
68
|
+
spyOn($scope, "$digest").and.callThrough();
|
|
69
|
+
|
|
70
|
+
const mutationObserverCallback =
|
|
71
|
+
MutationObserver.calls.mostRecent().args[0];
|
|
72
|
+
const mutationRecord = {
|
|
73
|
+
target: element[0],
|
|
74
|
+
attributeName: "test-attribute",
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
element.attr("test-attribute", "existingValue");
|
|
78
|
+
element[0].setAttribute("test-attribute", "existingValue");
|
|
79
|
+
|
|
80
|
+
mutationObserverCallback([mutationRecord]);
|
|
81
|
+
|
|
82
|
+
expect($scope.$digest).not.toHaveBeenCalled();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should disconnect the observer on scope destruction", () => {
|
|
86
|
+
createDirective("test-attribute", "myProp");
|
|
87
|
+
|
|
88
|
+
$scope.$destroy();
|
|
89
|
+
|
|
90
|
+
expect(observerSpy.disconnect).toHaveBeenCalled();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
test("unit observer tests contain no errors", async ({ page }) => {
|
|
4
|
+
await page.goto("src/directive/observe/observe.html");
|
|
5
|
+
await page.content();
|
|
6
|
+
await expect(page.locator(".jasmine-overall-result")).toHaveText(
|
|
7
|
+
/0 failures/,
|
|
8
|
+
);
|
|
9
|
+
});
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>AngularTS Test Runner</title>
|
|
6
|
+
|
|
7
|
+
<link rel="shortcut icon" type="image/png" href="/images/favicon.ico" />
|
|
8
|
+
<script type="module" src="/src/index.js"></script>
|
|
9
|
+
<link
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap"
|
|
11
|
+
rel="stylesheet"
|
|
12
|
+
/>
|
|
13
|
+
<script>
|
|
14
|
+
// Define a custom web component called <test-component>
|
|
15
|
+
class TestComponent extends HTMLElement {
|
|
16
|
+
// Called when the element is added to the DOM
|
|
17
|
+
connectedCallback() {
|
|
18
|
+
// Get the value of the 'greeting' attribute
|
|
19
|
+
const greeting = this.getAttribute("greeting") || "world";
|
|
20
|
+
|
|
21
|
+
// Set the inner HTML to display the greeting
|
|
22
|
+
this.innerHTML = `<p>Hello ${greeting}</p>`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Define which attributes to observe
|
|
26
|
+
static get observedAttributes() {
|
|
27
|
+
return ["greeting"];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Called when an observed attribute changes
|
|
31
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
32
|
+
if (name === "greeting") {
|
|
33
|
+
this.innerHTML = `<p>Hello ${newValue}</p>`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Register the custom element
|
|
39
|
+
customElements.define("test-component", TestComponent);
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
44
|
+
var app = window.angular.module("myApp", []);
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
<script type="module">
|
|
48
|
+
import {
|
|
49
|
+
fluentSelect,
|
|
50
|
+
fluentOption,
|
|
51
|
+
fluentTab,
|
|
52
|
+
fluentTabPanel,
|
|
53
|
+
fluentTabs,
|
|
54
|
+
provideFluentDesignSystem,
|
|
55
|
+
fluentRadio,
|
|
56
|
+
fluentRadioGroup,
|
|
57
|
+
fluentSwitch,
|
|
58
|
+
} from "https://unpkg.com/@fluentui/web-components@2.0.0";
|
|
59
|
+
provideFluentDesignSystem().register(
|
|
60
|
+
fluentSelect(),
|
|
61
|
+
fluentTab(),
|
|
62
|
+
fluentTabPanel(),
|
|
63
|
+
fluentTabs(),
|
|
64
|
+
fluentRadio(),
|
|
65
|
+
fluentRadioGroup(),
|
|
66
|
+
fluentSwitch(),
|
|
67
|
+
);
|
|
68
|
+
</script>
|
|
69
|
+
</head>
|
|
70
|
+
<body ng-app="myApp">
|
|
71
|
+
<div id="dummy">{{ greeting }}</div>
|
|
72
|
+
<input ng-model="greeting" />
|
|
73
|
+
|
|
74
|
+
<test-component greeting="{{ greeting }}"></test-component>
|
|
75
|
+
<div>{{ greeting }}</div>
|
|
76
|
+
|
|
77
|
+
<fluent-select
|
|
78
|
+
ng-observe="current-value"
|
|
79
|
+
data-update="greeting"
|
|
80
|
+
title="Select a section"
|
|
81
|
+
>
|
|
82
|
+
<fluent-option value="Beginning">Beginning</fluent-option>
|
|
83
|
+
<fluent-option value="Middle">Middle</fluent-option>
|
|
84
|
+
<fluent-option value="End">End</fluent-option>
|
|
85
|
+
</fluent-select>
|
|
86
|
+
<br />
|
|
87
|
+
|
|
88
|
+
{{ activeid }}
|
|
89
|
+
<fluent-tabs
|
|
90
|
+
ng-observe="activeid"
|
|
91
|
+
data-update="activeid"
|
|
92
|
+
activeid="entrees"
|
|
93
|
+
>
|
|
94
|
+
<fluent-tab id="apps">Appetizers</fluent-tab>
|
|
95
|
+
<fluent-tab id="entrees">Entrees</fluent-tab>
|
|
96
|
+
<fluent-tab id="desserts">Desserts</fluent-tab>
|
|
97
|
+
<fluent-tab-panel id="appsPanel">
|
|
98
|
+
<ol>
|
|
99
|
+
<li>
|
|
100
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
101
|
+
>Stuffed artichokes</fluent-anchor
|
|
102
|
+
>
|
|
103
|
+
</li>
|
|
104
|
+
<li>
|
|
105
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
106
|
+
>Bruschetta</fluent-anchor
|
|
107
|
+
>
|
|
108
|
+
</li>
|
|
109
|
+
<li>
|
|
110
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
111
|
+
>Oven-baked polenta</fluent-anchor
|
|
112
|
+
>
|
|
113
|
+
</li>
|
|
114
|
+
<li>
|
|
115
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
116
|
+
>Salami and Fig Crostini with Ricotta</fluent-anchor
|
|
117
|
+
>
|
|
118
|
+
</li>
|
|
119
|
+
<li>
|
|
120
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
121
|
+
>Rosemary-Potato Focaccia with Goat Cheese</fluent-anchor
|
|
122
|
+
>
|
|
123
|
+
</li>
|
|
124
|
+
</ol>
|
|
125
|
+
</fluent-tab-panel>
|
|
126
|
+
<fluent-tab-panel id="entreesPanel">
|
|
127
|
+
<ol>
|
|
128
|
+
<li>
|
|
129
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
130
|
+
>Mushroom-Sausage Ragù</fluent-anchor
|
|
131
|
+
>
|
|
132
|
+
</li>
|
|
133
|
+
<li>
|
|
134
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
135
|
+
>Tomato Bread Soup with Steamed Mussels</fluent-anchor
|
|
136
|
+
>
|
|
137
|
+
</li>
|
|
138
|
+
<li>
|
|
139
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
140
|
+
>Grilled Fish with Artichoke Caponata</fluent-anchor
|
|
141
|
+
>
|
|
142
|
+
</li>
|
|
143
|
+
<li>
|
|
144
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
145
|
+
>Celery Root and Mushroom Lasagna</fluent-anchor
|
|
146
|
+
>
|
|
147
|
+
</li>
|
|
148
|
+
<li>
|
|
149
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
150
|
+
>Osso Buco with Citrus Gremolata</fluent-anchor
|
|
151
|
+
>
|
|
152
|
+
</li>
|
|
153
|
+
</ol>
|
|
154
|
+
</fluent-tab-panel>
|
|
155
|
+
<fluent-tab-panel id="dessertsPanel">
|
|
156
|
+
<ol>
|
|
157
|
+
<li>
|
|
158
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
159
|
+
>Tiramisu</fluent-anchor
|
|
160
|
+
>
|
|
161
|
+
</li>
|
|
162
|
+
<li>
|
|
163
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
164
|
+
>Spumoni</fluent-anchor
|
|
165
|
+
>
|
|
166
|
+
</li>
|
|
167
|
+
<li>
|
|
168
|
+
<fluent-anchor href="#" appearance="hypertext"
|
|
169
|
+
>Limoncello and Ice Cream with Biscotti</fluent-anchor
|
|
170
|
+
>
|
|
171
|
+
</li>
|
|
172
|
+
</ol>
|
|
173
|
+
</fluent-tab-panel>
|
|
174
|
+
</fluent-tabs>
|
|
175
|
+
|
|
176
|
+
{{ radio }}
|
|
177
|
+
|
|
178
|
+
<fluent-radio-group
|
|
179
|
+
ng-observe="value"
|
|
180
|
+
data-update="radio"
|
|
181
|
+
orientation="vertical"
|
|
182
|
+
>
|
|
183
|
+
<fluent-radio value="1">18-24</fluent-radio>
|
|
184
|
+
<fluent-radio value="2">25-33</fluent-radio>
|
|
185
|
+
<fluent-radio value="3">34-44</fluent-radio>
|
|
186
|
+
<fluent-radio value="4">45+</fluent-radio>
|
|
187
|
+
</fluent-radio-group>
|
|
188
|
+
|
|
189
|
+
{{ checked }}
|
|
190
|
+
|
|
191
|
+
<fluent-switch ng-observe="aria-checked" data-update="checked">
|
|
192
|
+
<span slot="checked-message">On</span>
|
|
193
|
+
<span slot="unchecked-message">Off</span>
|
|
194
|
+
<label for="cap-switch">Captions:</label>
|
|
195
|
+
</fluent-switch>
|
|
196
|
+
</body>
|
|
197
|
+
</html>
|
package/src/public.js
CHANGED
|
@@ -75,7 +75,7 @@ import { LocationProvider } from "./core/location/location";
|
|
|
75
75
|
import { LogProvider } from "./services/log";
|
|
76
76
|
import { ParseProvider } from "./core/parser/parse";
|
|
77
77
|
import { RootScopeProvider } from "./core/scope/scope";
|
|
78
|
-
import { $QProvider
|
|
78
|
+
import { $QProvider } from "./core/q/q";
|
|
79
79
|
import { SceProvider, SceDelegateProvider } from "./core/sce/sce";
|
|
80
80
|
import { TaskTrackerFactoryProvider } from "./core/task-tracker-factory";
|
|
81
81
|
import { TemplateRequestProvider } from "./services/template-request";
|
|
@@ -116,8 +116,8 @@ import { UrlConfigProvider } from "./router/url/url-config";
|
|
|
116
116
|
import { UIRouterGlobals } from "./router/globals";
|
|
117
117
|
import { ViewService } from "./router/view/view";
|
|
118
118
|
import { TransitionProvider } from "./router/transition/transition-service";
|
|
119
|
-
import {
|
|
120
|
-
import {
|
|
119
|
+
import { StateProvider } from "./router/state/state-service";
|
|
120
|
+
import { ViewScrollProvider } from "./router/view-scroll";
|
|
121
121
|
import { TemplateFactoryProvider } from "./router/template-factory";
|
|
122
122
|
import { UrlService } from "./router/url/url-service";
|
|
123
123
|
import { StateRegistryProvider } from "./router/state/state-registry";
|
|
@@ -128,6 +128,7 @@ import {
|
|
|
128
128
|
$StateRefDynamicDirective,
|
|
129
129
|
} from "./router/directives/state-directives";
|
|
130
130
|
import { $ViewDirectiveFill, ngView } from "./router/directives/view-directive";
|
|
131
|
+
import { ngObserveDirective } from "./directive/observe/observe";
|
|
131
132
|
|
|
132
133
|
/**
|
|
133
134
|
* @type {string} `version` from `package.json`, injected by Rollup plugin
|
|
@@ -187,6 +188,7 @@ export function publishExternalAPI(angular) {
|
|
|
187
188
|
ngSwitch: ngSwitchDirective,
|
|
188
189
|
ngSwitchWhen: ngSwitchWhenDirective,
|
|
189
190
|
ngSwitchDefault: ngSwitchDefaultDirective,
|
|
191
|
+
ngObserve: ngObserveDirective,
|
|
190
192
|
ngOptions: ngOptionsDirective,
|
|
191
193
|
ngTransclude: ngTranscludeDirective,
|
|
192
194
|
ngModel: ngModelDirective,
|
|
@@ -259,7 +261,6 @@ export function publishExternalAPI(angular) {
|
|
|
259
261
|
$rootScope: RootScopeProvider,
|
|
260
262
|
$routerGlobals: UIRouterGlobals,
|
|
261
263
|
$q: $QProvider,
|
|
262
|
-
$$q: $$QProvider,
|
|
263
264
|
$sce: SceProvider,
|
|
264
265
|
$sceDelegate: SceDelegateProvider,
|
|
265
266
|
$$taskTrackerFactory: TaskTrackerFactoryProvider,
|
|
@@ -269,8 +270,8 @@ export function publishExternalAPI(angular) {
|
|
|
269
270
|
$urlConfig: UrlConfigProvider,
|
|
270
271
|
$view: ViewService,
|
|
271
272
|
$transitions: TransitionProvider,
|
|
272
|
-
$state:
|
|
273
|
-
$ngViewScroll:
|
|
273
|
+
$state: StateProvider,
|
|
274
|
+
$ngViewScroll: ViewScrollProvider,
|
|
274
275
|
$templateFactory: TemplateFactoryProvider,
|
|
275
276
|
$urlService: UrlService,
|
|
276
277
|
$stateRegistry: StateRegistryProvider,
|
|
@@ -27,7 +27,7 @@ const err = minErr("$stateProvider");
|
|
|
27
27
|
*
|
|
28
28
|
* This API is located at `router.stateService` ([[UIRouter.stateService]])
|
|
29
29
|
*/
|
|
30
|
-
export class
|
|
30
|
+
export class StateProvider {
|
|
31
31
|
/**
|
|
32
32
|
* The latest successful state parameters
|
|
33
33
|
*
|
|
@@ -73,11 +73,11 @@ export class StateService {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
const getters = ["current", "$current", "params", "transition"];
|
|
76
|
-
const boundFns = Object.keys(
|
|
76
|
+
const boundFns = Object.keys(StateProvider.prototype).filter(
|
|
77
77
|
(x) => !getters.includes(x),
|
|
78
78
|
);
|
|
79
79
|
createProxyFunctions(
|
|
80
|
-
val(
|
|
80
|
+
val(StateProvider.prototype),
|
|
81
81
|
this,
|
|
82
82
|
val(this),
|
|
83
83
|
boundFns,
|