@angular-wave/angular.ts 0.4.2 → 0.4.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/dist/angular-ts.esm.js +2 -2
- package/dist/angular-ts.umd.js +12 -2
- package/index.html +74 -3
- package/package.json +7 -7
- package/src/angular.spec.js +1 -269
- package/src/animations/animate-css-driver.js +2 -2
- package/src/animations/animate-css.js +12 -21
- package/src/animations/animate-js-driver.js +1 -3
- package/src/animations/animate-js.js +4 -4
- package/src/animations/animate-queue.js +23 -23
- package/src/animations/animate-runner.js +4 -8
- package/src/animations/animate.md +1 -1
- package/src/animations/animate.spec.js +0 -21
- package/src/animations/animation.js +4 -4
- package/src/animations/shared.js +14 -12
- package/src/binding.spec.js +0 -1
- package/src/core/cache/cache.js +2 -29
- package/src/core/compile/attributes.js +2 -3
- package/src/core/compile/compile.js +260 -245
- package/src/core/compile/compile.spec.js +63 -317
- package/src/core/compile/compile.test.js +1 -1
- package/src/core/controller/controller.js +2 -0
- package/src/core/di/injector.md +1 -1
- package/src/core/di/injector.spec.js +0 -2
- package/src/core/di/internal-injector.js +2 -1
- package/src/core/interpolate/interpolate.js +16 -3
- package/src/core/interpolate/interpolate.spec.js +70 -16
- package/src/core/location/location.js +0 -2
- package/src/core/location/location.spec.js +27 -27
- package/src/core/{scope/scope.html → model/model.html} +1 -1
- package/src/core/model/model.js +944 -0
- package/src/core/model/model.spec.js +3012 -0
- package/src/core/on.spec.js +0 -7
- package/src/core/parse/interpreter.js +10 -7
- package/src/core/parse/parse.js +28 -7
- package/src/core/parse/parse.spec.js +95 -91
- package/src/core/prop.spec.js +4 -60
- package/src/core/sce/sce.js +1 -2
- package/src/core/sce/sce.spec.js +0 -8
- package/src/core/scope/scope.js +62 -32
- package/src/core/scope/scope.spec.js +25 -1960
- package/src/directive/aria/aria.js +3 -6
- package/src/directive/aria/aria.spec.js +0 -87
- package/src/directive/attrs/attrs.spec.js +0 -5
- package/src/directive/{list/list.test.js → attrs/attrs.test.js} +1 -1
- package/src/{core/q/q.html → directive/attrs/boolean.html} +1 -1
- package/src/directive/attrs/boolean.spec.js +0 -15
- package/src/{core/q/q.test.js → directive/attrs/boolean.test.js} +1 -2
- package/src/{core/timeout/timeout.html → directive/attrs/element-style.html} +4 -1
- package/src/directive/attrs/element-style.spec.js +0 -8
- package/src/{core/scope/scope.test.js → directive/attrs/element-style.test.js} +1 -2
- package/src/directive/attrs/src.spec.js +0 -7
- package/src/directive/bind/bind.spec.js +0 -33
- package/src/directive/bind/bing-html.spec.js +1 -4
- package/src/{core/interval/interval.html → directive/channel/channel.html} +1 -1
- package/src/directive/channel/channel.js +29 -0
- package/src/directive/channel/channel.spec.js +52 -0
- package/src/directive/channel/channel.test.js +9 -0
- package/src/directive/class/class.js +3 -3
- package/src/directive/class/class.spec.js +9 -75
- package/src/directive/controller/controller.spec.js +0 -13
- package/src/directive/events/click.spec.js +0 -3
- package/src/directive/events/event.spec.js +0 -6
- package/src/directive/form/form.js +14 -22
- package/src/directive/form/form.spec.js +0 -65
- package/src/directive/if/if.spec.js +2 -7
- package/src/directive/if/if.test.js +1 -2
- package/src/directive/include/include.js +2 -2
- package/src/directive/include/include.spec.js +8 -59
- package/src/directive/init/init.js +6 -2
- package/src/directive/init/init.spec.js +0 -2
- package/src/directive/input/input.js +1 -2
- package/src/directive/input/input.spec.js +191 -331
- package/src/directive/messages/messages.spec.js +4 -35
- package/src/directive/model/model.js +30 -42
- package/src/directive/model/model.spec.js +2 -49
- package/src/directive/model-options/model-options.js +22 -26
- package/src/directive/model-options/model-options.spec.js +0 -6
- package/src/directive/non-bindable/non-bindable.spec.js +0 -1
- package/src/directive/observe/observe.js +0 -1
- package/src/directive/observe/observe.spec.js +0 -1
- package/src/directive/options/options.js +1 -3
- package/src/directive/options/options.spec.js +3 -38
- package/src/directive/ref/href.spec.js +0 -15
- package/src/directive/repeat/repeat.js +2 -2
- package/src/directive/repeat/repeat.spec.js +56 -192
- package/src/directive/script/script.spec.js +0 -2
- package/src/directive/select/select.js +3 -3
- package/src/directive/select/select.spec.js +9 -106
- package/src/directive/show-hide/show-hide.js +2 -2
- package/src/directive/show-hide/show-hide.spec.js +8 -19
- package/src/directive/style/style.spec.js +0 -7
- package/src/directive/switch/switch.js +1 -2
- package/src/directive/switch/switch.spec.js +5 -5
- package/src/directive/validators/validators.spec.js +0 -1
- package/src/loader.js +0 -1
- package/src/public.js +75 -80
- package/src/router/common/coreservices.js +0 -2
- package/src/router/directives/state-directives.js +24 -30
- package/src/router/directives/state-directives.spec.js +0 -83
- package/src/router/directives/view-directive.js +6 -15
- package/src/router/directives/view-directive.spec.js +25 -71
- package/src/router/hooks/lazy-load.js +2 -2
- package/src/router/hooks/views.js +3 -5
- package/src/router/resolve/resolvable.js +3 -6
- package/src/router/resolve/resolve-context.js +2 -2
- package/src/router/state/state-service.js +4 -4
- package/src/router/state/state.spec.js +2 -5
- package/src/router/state/views.js +9 -12
- package/src/router/template-factory.js +3 -6
- package/src/router/template-factory.spec.js +0 -4
- package/src/router/transition/transition-hook.js +1 -1
- package/src/router/transition/transition.js +1 -1
- package/src/router/url/url-service.js +2 -8
- package/src/router/url/url-service.spec.js +3 -4
- package/src/router/view-hook.spec.js +2 -2
- package/src/router/view-scroll.js +4 -6
- package/src/services/http/http.js +11 -15
- package/src/services/http/http.spec.js +30 -31
- package/src/services/http/template-request.spec.js +0 -10
- package/src/services/http-backend/http-backend.js +19 -17
- package/src/services/http-backend/http-backend.spec.js +3 -3
- package/src/services/template-request.js +2 -4
- package/src/shared/common.js +6 -10
- package/src/shared/jqlite/jqlite.js +14 -15
- package/src/shared/jqlite/jqlite.spec.js +2 -2
- package/src/shared/utils.js +15 -92
- package/types/core/cache/cache.d.ts +1 -1
- package/types/core/model/model.d.ts +204 -0
- package/types/core/parse/parse.d.ts +26 -0
- package/types/core/scope/scope.d.ts +22 -21
- package/types/directive/channel/channel.d.ts +11 -0
- package/types/directive/form/form.d.ts +1 -0
- package/types/shared/common.d.ts +0 -1
- package/types/shared/utils.d.ts +0 -35
- package/src/core/interval/interval-factory.js +0 -50
- package/src/core/interval/interval.js +0 -77
- package/src/core/interval/interval.md +0 -123
- package/src/core/interval/interval.spec.js +0 -280
- package/src/core/q/q.js +0 -472
- package/src/core/q/q.md +0 -211
- package/src/core/q/q.spec.js +0 -2748
- package/src/core/timeout/timeout.js +0 -109
- package/src/core/timeout/timeout.spec.js +0 -354
- package/src/core/timeout/timout.test.js +0 -12
- package/src/directive/list/list.html +0 -18
- package/src/directive/list/list.js +0 -46
- package/src/directive/list/list.md +0 -22
- package/src/directive/list/list.spec.js +0 -172
- package/types/directive/list/list.d.ts +0 -4
|
@@ -0,0 +1,944 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isUndefined,
|
|
3
|
+
nextUid,
|
|
4
|
+
isObject,
|
|
5
|
+
concat,
|
|
6
|
+
isFunction,
|
|
7
|
+
assert,
|
|
8
|
+
isString,
|
|
9
|
+
} from "../../shared/utils.js";
|
|
10
|
+
import { ASTType } from "../parse/ast-type.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {import('../parse/parse.js').ParseService}
|
|
14
|
+
*/
|
|
15
|
+
let $parse;
|
|
16
|
+
|
|
17
|
+
/**@type {import('../exception-handler').ErrorHandler} */
|
|
18
|
+
let $exceptionHandler;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {Object} AsyncQueueTask
|
|
22
|
+
* @property {Model} handler
|
|
23
|
+
* @property {Function} fn
|
|
24
|
+
* @property {Object} locals
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export const $postUpdateQueue = [];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @type {Function[]}
|
|
31
|
+
*/
|
|
32
|
+
export const $$applyAsyncQueue = [];
|
|
33
|
+
|
|
34
|
+
export class RootModelProvider {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.rootModel = createModel();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
$get = [
|
|
40
|
+
"$exceptionHandler",
|
|
41
|
+
"$parse",
|
|
42
|
+
"$browser",
|
|
43
|
+
/**
|
|
44
|
+
* @param {import('../exception-handler').ErrorHandler} exceptionHandler
|
|
45
|
+
* @param {import('../parse/parse.js').ParseService} parse
|
|
46
|
+
*/
|
|
47
|
+
(exceptionHandler, parse) => {
|
|
48
|
+
$exceptionHandler = exceptionHandler;
|
|
49
|
+
$parse = parse;
|
|
50
|
+
return this.rootModel;
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a deep proxy for the target object, intercepting property changes
|
|
57
|
+
* and recursively applying proxies to nested objects.
|
|
58
|
+
*
|
|
59
|
+
* @param {Object} target - The object to be wrapped in a proxy.
|
|
60
|
+
* @param {Model} [context] - The context for the handler, used to track listeners.
|
|
61
|
+
* @returns {ProxyHandler<Object>} - A proxy that intercepts operations on the target object,
|
|
62
|
+
* or the original value if the target is not an object.
|
|
63
|
+
*/
|
|
64
|
+
export function createModel(target = {}, context) {
|
|
65
|
+
if (typeof target === "object" && target !== null) {
|
|
66
|
+
for (const key in target) {
|
|
67
|
+
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
|
68
|
+
target[key] = createModel(target[key], new Model(target, context));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new Proxy(target, new Model(target, context));
|
|
72
|
+
} else {
|
|
73
|
+
return target;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Listener function definition.
|
|
79
|
+
* @typedef {Object} Listener
|
|
80
|
+
* @property {Object} originalTarget - The original target object.
|
|
81
|
+
* @property {ListenerFunction} listenerFn - The function invoked when changes are detected.
|
|
82
|
+
* @property {import("../parse/parse.js").CompiledExpression} watchFn
|
|
83
|
+
* @property {number} id
|
|
84
|
+
* @property {boolean} oneTime
|
|
85
|
+
* @property {string} property
|
|
86
|
+
* @property {Object} [context] - The optional context in which a property exists
|
|
87
|
+
* @property {Proxy} [foreignListener]
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Listener function type.
|
|
92
|
+
* @callback ListenerFunction
|
|
93
|
+
* @param {*} newValue - The new value of the changed property.
|
|
94
|
+
* @param {*} oldValue - The old value of the changed property.
|
|
95
|
+
* @param {Object} originalTarget - The original target object.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
export const isProxySymbol = Symbol("isProxy");
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @enum {number}
|
|
102
|
+
*/
|
|
103
|
+
export const ModelPhase = {
|
|
104
|
+
NONE: 0,
|
|
105
|
+
WATCH: 1,
|
|
106
|
+
DIGEST: 2,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Model class for the Proxy. It intercepts operations like property access (get)
|
|
111
|
+
* and property setting (set), and adds support for deep change tracking and
|
|
112
|
+
* observer-like behavior.
|
|
113
|
+
*/
|
|
114
|
+
class Model {
|
|
115
|
+
/**
|
|
116
|
+
* Initializes the handler with the target object and a context.
|
|
117
|
+
*
|
|
118
|
+
* @param {Object} target - The target object being proxied.
|
|
119
|
+
* @param {Model} [context] - The context containing listeners.
|
|
120
|
+
*/
|
|
121
|
+
constructor(target, context) {
|
|
122
|
+
/** @type {Object} */
|
|
123
|
+
this.$target = target;
|
|
124
|
+
|
|
125
|
+
this.context = context
|
|
126
|
+
? context.context
|
|
127
|
+
? context.context
|
|
128
|
+
: context
|
|
129
|
+
: undefined;
|
|
130
|
+
|
|
131
|
+
/** @type {Map<string, Array<Listener>>} Watch listeners */
|
|
132
|
+
this.listeners = context ? context.listeners : new Map();
|
|
133
|
+
|
|
134
|
+
/** @type {Map<string, Array<Listener>>} Watch listeners from other proxies */
|
|
135
|
+
this.foreignListeners = context ? context.foreignListeners : new Map();
|
|
136
|
+
|
|
137
|
+
/** @type {WeakMap<Object, Array<string>>} */
|
|
138
|
+
this.objectListeners = context ? context.objectListeners : new WeakMap();
|
|
139
|
+
|
|
140
|
+
/** @type {Map<Function, {oldValue: any, fn: Function}>} */
|
|
141
|
+
this.functionListeners = context ? context.functionListeners : new Map();
|
|
142
|
+
|
|
143
|
+
/** @type {?number} */
|
|
144
|
+
this.listenerCache = null;
|
|
145
|
+
|
|
146
|
+
/** @type {Proxy} */
|
|
147
|
+
this.proxy = null;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @type {Proxy[]}
|
|
151
|
+
*/
|
|
152
|
+
this.children = [];
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @type {number} Unique model ID (monotonically increasing) useful for debugging.
|
|
156
|
+
*/
|
|
157
|
+
this.id = nextUid();
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @type {Model}
|
|
161
|
+
*/
|
|
162
|
+
this.$root = context ? context.$root : this;
|
|
163
|
+
|
|
164
|
+
this.$parent = this.$root === this ? null : context;
|
|
165
|
+
|
|
166
|
+
/** @type {number} */
|
|
167
|
+
this.$$watchersCount = 0;
|
|
168
|
+
|
|
169
|
+
/** @type {AsyncQueueTask[]} */
|
|
170
|
+
this.$$asyncQueue = [];
|
|
171
|
+
|
|
172
|
+
/** @type {Map<String, Function[]>} Event listeners */
|
|
173
|
+
this.$$listeners = new Map();
|
|
174
|
+
|
|
175
|
+
this.filters = [];
|
|
176
|
+
|
|
177
|
+
/** @type {ModelPhase} */
|
|
178
|
+
this.state = ModelPhase.NONE;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Intercepts and handles property assignments on the target object. If a new value is
|
|
183
|
+
* an object, it will be recursively proxied.
|
|
184
|
+
*
|
|
185
|
+
* @param {Object} target - The target object.
|
|
186
|
+
* @param {string} property - The name of the property being set.
|
|
187
|
+
* @param {*} value - The new value being assigned to the property.
|
|
188
|
+
* @returns {boolean} - Returns true to indicate success of the operation.
|
|
189
|
+
*/
|
|
190
|
+
set(target, property, value, proxy) {
|
|
191
|
+
this.proxy = proxy;
|
|
192
|
+
const oldValue = target[property];
|
|
193
|
+
if (oldValue && oldValue[isProxySymbol]) {
|
|
194
|
+
if (Array.isArray(value)) {
|
|
195
|
+
if (oldValue !== value) {
|
|
196
|
+
const listeners = this.listeners.get(property);
|
|
197
|
+
|
|
198
|
+
if (listeners) {
|
|
199
|
+
this.scheduleListener(listeners, oldValue);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const foreignListeners = this.foreignListeners.get(property);
|
|
203
|
+
|
|
204
|
+
if (foreignListeners) {
|
|
205
|
+
this.scheduleListener(foreignListeners, oldValue);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
target[property] = value;
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
if (isObject(value)) {
|
|
212
|
+
if (Object.prototype.hasOwnProperty.call(target, property)) {
|
|
213
|
+
Object.keys(oldValue)
|
|
214
|
+
.filter((x) => !value[x])
|
|
215
|
+
.forEach((k) => {
|
|
216
|
+
delete oldValue[k];
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (oldValue !== value) {
|
|
221
|
+
const listeners = this.listeners.get(property);
|
|
222
|
+
|
|
223
|
+
if (listeners) {
|
|
224
|
+
this.scheduleListener(listeners, oldValue);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const foreignListeners = this.foreignListeners.get(property);
|
|
228
|
+
|
|
229
|
+
if (foreignListeners) {
|
|
230
|
+
this.scheduleListener(foreignListeners, oldValue);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
target[property] = createModel({}, this);
|
|
234
|
+
setDeepValue(target[property], value);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (isUndefined(value)) {
|
|
239
|
+
Object.keys(oldValue.$target).forEach((k) => {
|
|
240
|
+
delete oldValue[k];
|
|
241
|
+
});
|
|
242
|
+
target[property] = undefined;
|
|
243
|
+
const listeners = this.listeners.get(property);
|
|
244
|
+
|
|
245
|
+
if (listeners) {
|
|
246
|
+
this.scheduleListener(listeners, oldValue);
|
|
247
|
+
}
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
} else {
|
|
252
|
+
if (
|
|
253
|
+
oldValue !== undefined &&
|
|
254
|
+
Number.isNaN(oldValue) &&
|
|
255
|
+
Number.isNaN(value)
|
|
256
|
+
) {
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
target[property] = createModel(value, this);
|
|
261
|
+
|
|
262
|
+
if (oldValue !== value) {
|
|
263
|
+
const listeners = this.listeners.get(property);
|
|
264
|
+
|
|
265
|
+
if (listeners) {
|
|
266
|
+
assert(listeners.length !== 0);
|
|
267
|
+
// primitive only
|
|
268
|
+
|
|
269
|
+
let isValue =
|
|
270
|
+
Number.isNaN(value) ||
|
|
271
|
+
listeners[0].watchFn(this.context?.$target) == value ||
|
|
272
|
+
(() => {
|
|
273
|
+
const res = listeners[0].watchFn(this.$target);
|
|
274
|
+
if (res && res[isProxySymbol]) {
|
|
275
|
+
return res.$target == value;
|
|
276
|
+
} else {
|
|
277
|
+
return res == value;
|
|
278
|
+
}
|
|
279
|
+
})();
|
|
280
|
+
|
|
281
|
+
if (isValue) {
|
|
282
|
+
this.scheduleListener(listeners, oldValue);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const foreignListeners = this.foreignListeners.get(property);
|
|
287
|
+
|
|
288
|
+
if (foreignListeners) {
|
|
289
|
+
assert(foreignListeners.length !== 0);
|
|
290
|
+
// primitive only
|
|
291
|
+
|
|
292
|
+
// let isValue =
|
|
293
|
+
// Number.isNaN(value) ||
|
|
294
|
+
// foreignListeners[0].watchFn(this.context?.$target) == value ||
|
|
295
|
+
// (() => {
|
|
296
|
+
// const res = foreignListeners[0].watchFn(this.$target);
|
|
297
|
+
// if (res && res[isProxySymbol]) {
|
|
298
|
+
// return res.$target == value;
|
|
299
|
+
// } else {
|
|
300
|
+
// return res == value;
|
|
301
|
+
// }
|
|
302
|
+
// })();
|
|
303
|
+
|
|
304
|
+
// if (isValue) {
|
|
305
|
+
this.scheduleListener(foreignListeners, oldValue);
|
|
306
|
+
//}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Right now this is only for Arrays
|
|
311
|
+
if (this.objectListeners.has(target) && property !== "length") {
|
|
312
|
+
let keys = this.objectListeners.get(target);
|
|
313
|
+
keys.forEach((key) => {
|
|
314
|
+
const listeners = this.listeners.get(key);
|
|
315
|
+
if (listeners) {
|
|
316
|
+
this.scheduleListener(listeners, oldValue);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Intercepts property access on the target object. It checks for specific
|
|
327
|
+
* properties (`watch` and `sync`) and binds their methods. For other properties,
|
|
328
|
+
* it returns the value directly.
|
|
329
|
+
*
|
|
330
|
+
* @param {Object} target - The target object.
|
|
331
|
+
* @param {string|number|symbol} property - The name of the property being accessed.
|
|
332
|
+
* @param {Proxy} proxy - The proxy object being invoked
|
|
333
|
+
* @returns {*} - The value of the property or a method if accessing `watch` or `sync`.
|
|
334
|
+
*/
|
|
335
|
+
get(target, property, proxy) {
|
|
336
|
+
this.proxy = proxy;
|
|
337
|
+
|
|
338
|
+
if (property === isProxySymbol) return true;
|
|
339
|
+
const propertyMap = {
|
|
340
|
+
$watch: this.$watch.bind(this),
|
|
341
|
+
$watchGroup: this.$watchGroup.bind(this),
|
|
342
|
+
$watchCollection: this.$watchCollection.bind(this),
|
|
343
|
+
$new: this.$new.bind(this),
|
|
344
|
+
$destroy: this.$destroy.bind(this),
|
|
345
|
+
$eval: this.$eval.bind(this),
|
|
346
|
+
$apply: this.$apply.bind(this),
|
|
347
|
+
$evalAsync: this.$evalAsync.bind(this),
|
|
348
|
+
$postUpdate: this.$postUpdate.bind(this),
|
|
349
|
+
$isRoot: this.isRoot.bind(this),
|
|
350
|
+
$target: this.$target,
|
|
351
|
+
$digest: this.$digest.bind(this),
|
|
352
|
+
$on: this.$on.bind(this),
|
|
353
|
+
$emit: this.$emit.bind(this),
|
|
354
|
+
$broadcast: this.$broadcast.bind(this),
|
|
355
|
+
$transcluded: this.$transcluded.bind(this),
|
|
356
|
+
$handler: this,
|
|
357
|
+
$parent: this.$parent,
|
|
358
|
+
$root: this.$root,
|
|
359
|
+
$$watchersCount: this.$$watchersCount,
|
|
360
|
+
$children: this.children,
|
|
361
|
+
id: this.id,
|
|
362
|
+
state: this.state,
|
|
363
|
+
registerForeignKey: this.registerForeignKey.bind(this),
|
|
364
|
+
notifyListener: this.notifyListener.bind(this),
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
return Object.prototype.hasOwnProperty.call(propertyMap, property)
|
|
368
|
+
? propertyMap[property]
|
|
369
|
+
: target[property];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @private
|
|
374
|
+
* @param {Listener[]} listeners
|
|
375
|
+
* @param {*} oldValue
|
|
376
|
+
*/
|
|
377
|
+
scheduleListener(listeners, oldValue) {
|
|
378
|
+
Promise.resolve().then(() => {
|
|
379
|
+
let index = 0;
|
|
380
|
+
while (index < listeners.length) {
|
|
381
|
+
const listener = listeners[index];
|
|
382
|
+
if (listener.foreignListener) {
|
|
383
|
+
listener.foreignListener.notifyListener(
|
|
384
|
+
listener,
|
|
385
|
+
oldValue,
|
|
386
|
+
this.$target,
|
|
387
|
+
);
|
|
388
|
+
} else {
|
|
389
|
+
this.notifyListener(listener, oldValue, this.$target);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (
|
|
393
|
+
listener.oneTime &&
|
|
394
|
+
this.deregisterKey(listener.property, listener.id)
|
|
395
|
+
) {
|
|
396
|
+
this.incrementWatchersCount(-1);
|
|
397
|
+
}
|
|
398
|
+
index++;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
deleteProperty(target, property) {
|
|
404
|
+
// Currently deletes $model
|
|
405
|
+
if (target[property] && target[property][isProxySymbol]) {
|
|
406
|
+
delete target[property];
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
var oldValue = structuredClone(target);
|
|
411
|
+
delete target[property];
|
|
412
|
+
if (this.objectListeners.has(target)) {
|
|
413
|
+
let keys = this.objectListeners.get(target);
|
|
414
|
+
keys.forEach((key) => {
|
|
415
|
+
const listeners = this.listeners.get(key);
|
|
416
|
+
if (listeners) {
|
|
417
|
+
this.scheduleListener(listeners, oldValue);
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
} else {
|
|
421
|
+
const listeners = this.listeners.get(property);
|
|
422
|
+
if (listeners) {
|
|
423
|
+
this.scheduleListener(listeners, target[property]);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Registers a watcher for a property along with a listener function. The listener
|
|
432
|
+
* function is invoked when changes to that property are detected.
|
|
433
|
+
*
|
|
434
|
+
* @param {string} watchProp - An expression to be watched in the context of this model.
|
|
435
|
+
* @param {ListenerFunction} [listenerFn] - A function to execute when changes are detected on watched context.
|
|
436
|
+
*/
|
|
437
|
+
$watch(watchProp, listenerFn) {
|
|
438
|
+
assert(isString(watchProp), "Watched property required");
|
|
439
|
+
this.state = ModelPhase.WATCH;
|
|
440
|
+
|
|
441
|
+
const get = $parse(watchProp);
|
|
442
|
+
|
|
443
|
+
// Constant are immediately passed to listener function
|
|
444
|
+
if (get.constant) {
|
|
445
|
+
if (listenerFn) {
|
|
446
|
+
Promise.resolve().then(() => {
|
|
447
|
+
let res = get();
|
|
448
|
+
while (isFunction(res)) {
|
|
449
|
+
res = res();
|
|
450
|
+
}
|
|
451
|
+
listenerFn(res, undefined, this.$target);
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
return () => {};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/** @type {Listener} */
|
|
458
|
+
const listener = {
|
|
459
|
+
originalTarget: this.$target,
|
|
460
|
+
listenerFn: listenerFn,
|
|
461
|
+
watchFn: get,
|
|
462
|
+
id: nextUid(),
|
|
463
|
+
oneTime: get.oneTime,
|
|
464
|
+
property: undefined,
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
// simplest case
|
|
468
|
+
let key = get.decoratedNode.body[0].expression.name;
|
|
469
|
+
|
|
470
|
+
let type = get.decoratedNode.body[0].expression.type;
|
|
471
|
+
switch (type) {
|
|
472
|
+
// 1
|
|
473
|
+
case ASTType.Program: {
|
|
474
|
+
throw new Error("Unsupported type " + type);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// 2
|
|
478
|
+
case ASTType.ExpressionStatement: {
|
|
479
|
+
throw new Error("Unsupported type " + type);
|
|
480
|
+
}
|
|
481
|
+
// 3
|
|
482
|
+
case ASTType.AssignmentExpression:
|
|
483
|
+
// assignment calls without listener functions
|
|
484
|
+
if (!listenerFn) {
|
|
485
|
+
let res = get(this.$target);
|
|
486
|
+
while (isFunction(res)) {
|
|
487
|
+
res = res(this.$target);
|
|
488
|
+
}
|
|
489
|
+
Promise.resolve().then(res);
|
|
490
|
+
return () => {};
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
// 4
|
|
494
|
+
case ASTType.ConditionalExpression: {
|
|
495
|
+
throw new Error("Unsupported type " + type);
|
|
496
|
+
}
|
|
497
|
+
// 5
|
|
498
|
+
case ASTType.LogicalExpression: {
|
|
499
|
+
throw new Error("Unsupported type " + type);
|
|
500
|
+
}
|
|
501
|
+
// 6
|
|
502
|
+
case ASTType.BinaryExpression: {
|
|
503
|
+
throw new Error("Unsupported type " + type);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// 7
|
|
507
|
+
case ASTType.UnaryExpression: {
|
|
508
|
+
throw new Error("Unsupported type " + type);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// function
|
|
512
|
+
case ASTType.CallExpression: {
|
|
513
|
+
listener.property = get.decoratedNode.body[0].callee.name;
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
case ASTType.MemberExpression: {
|
|
518
|
+
listener.property = get.decoratedNode.body[0].expression.property.name;
|
|
519
|
+
const name = extractTarget(get.decoratedNode.body[0].expression.object);
|
|
520
|
+
if (this.$target[name]) {
|
|
521
|
+
listener.context = () => {
|
|
522
|
+
return this.$target[name].$target;
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// 10
|
|
529
|
+
case ASTType.Identifier: {
|
|
530
|
+
listener.property = get.decoratedNode.body[0].expression.name;
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// 11
|
|
535
|
+
case ASTType.Literal: {
|
|
536
|
+
throw new Error("Unsupported type " + type);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// 12
|
|
540
|
+
case ASTType.ArrayExpression: {
|
|
541
|
+
throw new Error("Unsupported type " + type);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// 13
|
|
545
|
+
case ASTType.Property: {
|
|
546
|
+
throw new Error("Unsupported type " + type);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// 14
|
|
550
|
+
case ASTType.ObjectExpression: {
|
|
551
|
+
throw new Error("Unsupported type " + type);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// 15
|
|
555
|
+
case ASTType.ThisExpression: {
|
|
556
|
+
throw new Error("Unsupported type " + type);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// 16
|
|
560
|
+
case ASTType.LocalsExpression: {
|
|
561
|
+
throw new Error("Unsupported type " + type);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// 17
|
|
565
|
+
case ASTType.NGValueParameter: {
|
|
566
|
+
throw new Error("Unsupported type " + type);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (listener.context && listener.context()[isProxySymbol]) {
|
|
571
|
+
listener.foreignListener = this.proxy;
|
|
572
|
+
key = get.decoratedNode.body[0].expression.property.name;
|
|
573
|
+
listener.context().$handler.registerForeignKey(key, listener);
|
|
574
|
+
} else {
|
|
575
|
+
this.registerKey(key, listener);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
let watchedValue = get(this.$target);
|
|
579
|
+
const value =
|
|
580
|
+
watchedValue && watchedValue[isProxySymbol]
|
|
581
|
+
? watchedValue.$target
|
|
582
|
+
: watchedValue;
|
|
583
|
+
|
|
584
|
+
const isArray = Array.isArray(value);
|
|
585
|
+
const isObject =
|
|
586
|
+
Object.prototype.toString.call(value) === "[object Object]";
|
|
587
|
+
if (isArray || isObject) {
|
|
588
|
+
if (this.objectListeners.has(value)) {
|
|
589
|
+
this.objectListeners.get(value).push(key);
|
|
590
|
+
} else {
|
|
591
|
+
this.objectListeners.set(value, [key]);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
this.incrementWatchersCount(1);
|
|
596
|
+
this.state = ModelPhase.NONE;
|
|
597
|
+
return () => {
|
|
598
|
+
const res = this.deregisterKey(key, listener.id);
|
|
599
|
+
if (res) {
|
|
600
|
+
this.incrementWatchersCount(-1);
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
$watchGroup(watchArray, listenerFn) {
|
|
606
|
+
watchArray.forEach((x) => this.$watch(x, listenerFn));
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
$watchCollection(watchProp, listenerFn) {
|
|
610
|
+
return this.$watch(watchProp, listenerFn);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
$new(childInstance) {
|
|
614
|
+
let child;
|
|
615
|
+
if (childInstance) {
|
|
616
|
+
if (Object.getPrototypeOf(childInstance) === Object.prototype) {
|
|
617
|
+
Object.setPrototypeOf(childInstance, this.$target);
|
|
618
|
+
} else {
|
|
619
|
+
Object.setPrototypeOf(
|
|
620
|
+
Object.getPrototypeOf(childInstance),
|
|
621
|
+
this.$target,
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
child = childInstance;
|
|
626
|
+
} else {
|
|
627
|
+
child = Object.create(this.$target);
|
|
628
|
+
child.$$watchersCount = 0;
|
|
629
|
+
child.$parent = this.$parent;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const proxy = new Proxy(child, new Model(child, this));
|
|
633
|
+
this.children.push(proxy);
|
|
634
|
+
return proxy;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
$transcluded(parentInstance) {
|
|
638
|
+
let child = Object.create(this.$target);
|
|
639
|
+
child.$$watchersCount = 0;
|
|
640
|
+
child.$parent = parentInstance;
|
|
641
|
+
const proxy = new Proxy(child, new Model(child, this));
|
|
642
|
+
this.children.push(proxy);
|
|
643
|
+
return proxy;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
registerKey(key, listener) {
|
|
647
|
+
if (this.listeners.has(key)) {
|
|
648
|
+
this.listeners.get(key).push(listener);
|
|
649
|
+
} else {
|
|
650
|
+
this.listeners.set(key, [listener]);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
registerForeignKey(key, listener) {
|
|
655
|
+
if (this.foreignListeners.has(key)) {
|
|
656
|
+
this.foreignListeners.get(key).push(listener);
|
|
657
|
+
} else {
|
|
658
|
+
this.foreignListeners.set(key, [listener]);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
deregisterKey(key, id) {
|
|
663
|
+
const listenerList = this.listeners.get(key);
|
|
664
|
+
if (!listenerList) return false;
|
|
665
|
+
|
|
666
|
+
const index = listenerList.findIndex((x) => x.id === id);
|
|
667
|
+
if (index === -1) return false;
|
|
668
|
+
|
|
669
|
+
listenerList.splice(index, 1);
|
|
670
|
+
if (listenerList.length) {
|
|
671
|
+
this.listeners.set(key, listenerList);
|
|
672
|
+
} else {
|
|
673
|
+
this.listeners.delete(key);
|
|
674
|
+
}
|
|
675
|
+
return true;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
deregisterForeignKey(key, id) {
|
|
679
|
+
const listenerList = this.foreignListeners.get(key);
|
|
680
|
+
if (!listenerList) return false;
|
|
681
|
+
|
|
682
|
+
const index = listenerList.findIndex((x) => x.id === id);
|
|
683
|
+
if (index === -1) return false;
|
|
684
|
+
|
|
685
|
+
listenerList.splice(index, 1);
|
|
686
|
+
if (listenerList.length) {
|
|
687
|
+
this.foreignListeners.set(key, listenerList);
|
|
688
|
+
} else {
|
|
689
|
+
this.foreignListeners.delete(key);
|
|
690
|
+
}
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* @deprecated
|
|
696
|
+
*/
|
|
697
|
+
$digest() {
|
|
698
|
+
throw new Error("$Digest is deprecated");
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
$eval(expr, locals) {
|
|
702
|
+
const fn = $parse(expr);
|
|
703
|
+
const res = fn(this.$target, locals);
|
|
704
|
+
|
|
705
|
+
if (isUndefined(res) || res === null) {
|
|
706
|
+
return res;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
if (res["name"] === Object.hasOwnProperty["name"]) {
|
|
710
|
+
return res;
|
|
711
|
+
}
|
|
712
|
+
if (isFunction(res)) {
|
|
713
|
+
return res();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (Number.isNaN(res)) {
|
|
717
|
+
return 0;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return res;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
async $evalAsync(expr, locals) {
|
|
724
|
+
return this.$eval(expr, locals);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
$apply(expr) {
|
|
728
|
+
try {
|
|
729
|
+
return $parse(expr)(this.proxy);
|
|
730
|
+
} catch (e) {
|
|
731
|
+
$exceptionHandler(e);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
$on(name, listener) {
|
|
736
|
+
let namedListeners = this.$$listeners.get(name);
|
|
737
|
+
if (!namedListeners) {
|
|
738
|
+
namedListeners = [];
|
|
739
|
+
this.$$listeners.set(name, namedListeners);
|
|
740
|
+
}
|
|
741
|
+
namedListeners.push(listener);
|
|
742
|
+
|
|
743
|
+
return () => {
|
|
744
|
+
const indexOfListener = namedListeners.indexOf(listener);
|
|
745
|
+
if (indexOfListener !== -1) {
|
|
746
|
+
namedListeners.splice(indexOfListener, 1);
|
|
747
|
+
if (namedListeners.length == 0) {
|
|
748
|
+
this.$$listeners.delete(name);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* @param {string} name
|
|
756
|
+
* @param {...any} args
|
|
757
|
+
* @returns
|
|
758
|
+
*/
|
|
759
|
+
$emit(name, ...args) {
|
|
760
|
+
return this.eventHelper(
|
|
761
|
+
{ name: name, event: undefined, broadcast: false },
|
|
762
|
+
...args,
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* @param {string} name
|
|
768
|
+
* @param {...any} args
|
|
769
|
+
* @returns
|
|
770
|
+
*/
|
|
771
|
+
$broadcast(name, ...args) {
|
|
772
|
+
return this.eventHelper(
|
|
773
|
+
{ name: name, event: undefined, broadcast: true },
|
|
774
|
+
...args,
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
eventHelper({ name, event, broadcast }, ...args) {
|
|
779
|
+
if (!broadcast) {
|
|
780
|
+
if (!this.$$listeners.has(name)) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (event) {
|
|
785
|
+
event.currentScope = this.$target;
|
|
786
|
+
} else {
|
|
787
|
+
event = event || {
|
|
788
|
+
name,
|
|
789
|
+
targetScope: this.$target,
|
|
790
|
+
currentScope: this.$target,
|
|
791
|
+
stopped: false,
|
|
792
|
+
stopPropagation() {
|
|
793
|
+
event.stopped = true;
|
|
794
|
+
},
|
|
795
|
+
preventDefault() {
|
|
796
|
+
event.defaultPrevented = true;
|
|
797
|
+
},
|
|
798
|
+
defaultPrevented: false,
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
const listenerArgs = concat([event], [event].concat(args), 1);
|
|
803
|
+
let listeners = this.$$listeners.get(name);
|
|
804
|
+
if (listeners) {
|
|
805
|
+
let length = listeners.length;
|
|
806
|
+
for (let i = 0; i < length; i++) {
|
|
807
|
+
try {
|
|
808
|
+
let cb = listeners[i];
|
|
809
|
+
cb.apply(null, listenerArgs);
|
|
810
|
+
if (listeners.length !== length) {
|
|
811
|
+
if (listeners.length < length) {
|
|
812
|
+
i--;
|
|
813
|
+
}
|
|
814
|
+
length = listeners.length;
|
|
815
|
+
}
|
|
816
|
+
} catch (e) {
|
|
817
|
+
$exceptionHandler(e);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
event.currentScope = null;
|
|
823
|
+
|
|
824
|
+
if (event.stopped) {
|
|
825
|
+
return event;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (broadcast) {
|
|
829
|
+
if (this.children.length > 0) {
|
|
830
|
+
this.children.forEach((child) => {
|
|
831
|
+
event = child["$handler"].eventHelper(
|
|
832
|
+
{ name: name, event: event, broadcast: broadcast },
|
|
833
|
+
...args,
|
|
834
|
+
);
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
return event;
|
|
838
|
+
} else {
|
|
839
|
+
if (this.$parent) {
|
|
840
|
+
return this.$parent?.eventHelper(
|
|
841
|
+
{ name: name, event: event, broadcast: broadcast },
|
|
842
|
+
...args,
|
|
843
|
+
);
|
|
844
|
+
} else {
|
|
845
|
+
return event;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* @private
|
|
852
|
+
* @returns {boolean}
|
|
853
|
+
*/
|
|
854
|
+
isRoot() {
|
|
855
|
+
return this.$root == this;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
async $applyAsync(expr) {
|
|
859
|
+
try {
|
|
860
|
+
const result = $parse(expr)(this.proxy);
|
|
861
|
+
return result;
|
|
862
|
+
} catch (error) {
|
|
863
|
+
$exceptionHandler(error);
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
$postUpdate(fn) {
|
|
869
|
+
$postUpdateQueue.push(fn);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
$destroy() {
|
|
873
|
+
this.incrementWatchersCount(-this.$$watchersCount);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* @param {number} count
|
|
878
|
+
*/
|
|
879
|
+
incrementWatchersCount(count) {
|
|
880
|
+
this.$$watchersCount += count;
|
|
881
|
+
if (this.$parent) {
|
|
882
|
+
this.$parent.incrementWatchersCount(count);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* Invokes the registered listener function with watched property changes.
|
|
888
|
+
*
|
|
889
|
+
* @param {Listener} listener - The property path that was changed.
|
|
890
|
+
* @param {*} oldValue - The old value of the property.
|
|
891
|
+
*/
|
|
892
|
+
notifyListener(listener, oldValue, target) {
|
|
893
|
+
const { originalTarget, listenerFn, watchFn } = listener;
|
|
894
|
+
try {
|
|
895
|
+
const newVal = watchFn(target || listener.originalTarget);
|
|
896
|
+
//const res = watchFn(listener.originalTarget.$target).$target
|
|
897
|
+
listenerFn(newVal, oldValue, originalTarget);
|
|
898
|
+
// if (oneTime) {
|
|
899
|
+
// this.deregisterKey(property, id)
|
|
900
|
+
// }
|
|
901
|
+
|
|
902
|
+
this.$$asyncQueue.forEach((x) => {
|
|
903
|
+
if (x.handler.id == this.id) {
|
|
904
|
+
Promise.resolve().then(x.fn(x.handler, x.locals));
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
while ($postUpdateQueue.length) {
|
|
909
|
+
$postUpdateQueue.shift()();
|
|
910
|
+
}
|
|
911
|
+
} catch (e) {
|
|
912
|
+
$exceptionHandler(e);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
function setDeepValue(model, obj) {
|
|
918
|
+
for (const key in obj) {
|
|
919
|
+
if (isObject(obj[key]) && !Array.isArray(obj[key])) {
|
|
920
|
+
if (!isObject(model[key])) {
|
|
921
|
+
model[key] = {};
|
|
922
|
+
}
|
|
923
|
+
setDeepValue(model[key], obj[key]);
|
|
924
|
+
} else {
|
|
925
|
+
model[key] = obj[key];
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
function extractTarget(object) {
|
|
931
|
+
if (!object.name) {
|
|
932
|
+
return extractTarget(object.object);
|
|
933
|
+
} else {
|
|
934
|
+
return object.name;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// function deProxy(maybeProxy) {
|
|
939
|
+
// if (maybeProxy[isProxySymbol]) {
|
|
940
|
+
// return deProxy(maybeProxy);
|
|
941
|
+
// } else {
|
|
942
|
+
// return maybeProxy.$target;
|
|
943
|
+
// }
|
|
944
|
+
// }
|