@genesislcap/foundation-events 10.3.1 → 11.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/eventEmitter/eventEmitterDI.js +0 -1
- package/dist/esm/eventEmitter/eventEmitterMixin.js +0 -1
- package/dist/esm/eventEmitter/index.js +0 -1
- package/dist/esm/index.federated.js +0 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/types.js +0 -1
- package/package.json +3 -4
- package/dist/1.0.0.remoteEntry.js +0 -1
- package/dist/573.573.6e60854155addcc72467.js +0 -2
- package/dist/573.650390e975bc6c8376d3ff8eda7e52f4.js.map +0 -1
- package/dist/755.537dff5a23d468b98824bdef43b0cda0.js.map +0 -1
- package/dist/755.755.e981769af6aec9db513d.js +0 -2
- package/dist/856.3e4045c8104c25006236673f533997ff.js.map +0 -1
- package/dist/856.856.72fdef7363783c3bf498.js +0 -3
- package/dist/856.856.72fdef7363783c3bf498.js.LICENSE.txt +0 -4
- package/dist/dashboard.json +0 -1
- package/dist/esm/eventEmitter/eventEmitterDI.js.map +0 -1
- package/dist/esm/eventEmitter/eventEmitterMixin.js.map +0 -1
- package/dist/esm/eventEmitter/index.js.map +0 -1
- package/dist/esm/index.federated.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/types.js.map +0 -1
- package/dist/favicon.ico +0 -0
- package/dist/foundation-events.iife.min.js +0 -1
- package/dist/foundation-events.js +0 -2728
- package/dist/foundation-events.min.js +0 -1
- package/dist/foundationEvents.8f5b3182da29e4d9304d1d4c151e3e58.js.map +0 -1
- package/dist/index.ejs +0 -23
- package/dist/index.html +0 -13
- package/dist/info.ejs +0 -13
- package/dist/main.50811a618c5e054436cd.js +0 -2
- package/dist/main.db9310a7c29193d4ad3bbbeeb42b7729.js.map +0 -1
- package/dist/npm.microsoft.127.08b9ac45e34e116d147c.js +0 -1469
- package/dist/npm.microsoft.127.08b9ac45e34e116d147c.js.LICENSE.txt +0 -14
- package/dist/npm.microsoft.c693b5fe4306901c8d3cdd3b3c894944.js.map +0 -1
- package/dist/remoteEntry.js +0 -2
- package/dist/serve.json +0 -3
|
@@ -1,2728 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A reference to globalThis, with support
|
|
3
|
-
* for browsers that don't yet support the spec.
|
|
4
|
-
* @public
|
|
5
|
-
*/
|
|
6
|
-
const $global = function () {
|
|
7
|
-
if (typeof globalThis !== "undefined") {
|
|
8
|
-
// We're running in a modern environment.
|
|
9
|
-
return globalThis;
|
|
10
|
-
}
|
|
11
|
-
if (typeof global !== "undefined") {
|
|
12
|
-
// We're running in NodeJS
|
|
13
|
-
return global;
|
|
14
|
-
}
|
|
15
|
-
if (typeof self !== "undefined") {
|
|
16
|
-
// We're running in a worker.
|
|
17
|
-
return self;
|
|
18
|
-
}
|
|
19
|
-
if (typeof window !== "undefined") {
|
|
20
|
-
// We're running in the browser's main thread.
|
|
21
|
-
return window;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
// Hopefully we never get here...
|
|
25
|
-
// Not all environments allow eval and Function. Use only as a last resort:
|
|
26
|
-
// eslint-disable-next-line no-new-func
|
|
27
|
-
return new Function("return this")();
|
|
28
|
-
} catch (_a) {
|
|
29
|
-
// If all fails, give up and create an object.
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
31
|
-
return {};
|
|
32
|
-
}
|
|
33
|
-
}();
|
|
34
|
-
// API-only Polyfill for trustedTypes
|
|
35
|
-
if ($global.trustedTypes === void 0) {
|
|
36
|
-
$global.trustedTypes = {
|
|
37
|
-
createPolicy: (n, r) => r
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
const propConfig = {
|
|
41
|
-
configurable: false,
|
|
42
|
-
enumerable: false,
|
|
43
|
-
writable: false
|
|
44
|
-
};
|
|
45
|
-
if ($global.FAST === void 0) {
|
|
46
|
-
Reflect.defineProperty($global, "FAST", Object.assign({
|
|
47
|
-
value: Object.create(null)
|
|
48
|
-
}, propConfig));
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* The FAST global.
|
|
52
|
-
* @internal
|
|
53
|
-
*/
|
|
54
|
-
const FAST = $global.FAST;
|
|
55
|
-
if (FAST.getById === void 0) {
|
|
56
|
-
const storage = Object.create(null);
|
|
57
|
-
Reflect.defineProperty(FAST, "getById", Object.assign({
|
|
58
|
-
value(id, initialize) {
|
|
59
|
-
let found = storage[id];
|
|
60
|
-
if (found === void 0) {
|
|
61
|
-
found = initialize ? storage[id] = initialize() : null;
|
|
62
|
-
}
|
|
63
|
-
return found;
|
|
64
|
-
}
|
|
65
|
-
}, propConfig));
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* A readonly, empty array.
|
|
69
|
-
* @remarks
|
|
70
|
-
* Typically returned by APIs that return arrays when there are
|
|
71
|
-
* no actual items to return.
|
|
72
|
-
* @internal
|
|
73
|
-
*/
|
|
74
|
-
const emptyArray = Object.freeze([]);
|
|
75
|
-
/**
|
|
76
|
-
* Creates a function capable of locating metadata associated with a type.
|
|
77
|
-
* @returns A metadata locator function.
|
|
78
|
-
* @internal
|
|
79
|
-
*/
|
|
80
|
-
function createMetadataLocator() {
|
|
81
|
-
const metadataLookup = new WeakMap();
|
|
82
|
-
return function (target) {
|
|
83
|
-
let metadata = metadataLookup.get(target);
|
|
84
|
-
if (metadata === void 0) {
|
|
85
|
-
let currentTarget = Reflect.getPrototypeOf(target);
|
|
86
|
-
while (metadata === void 0 && currentTarget !== null) {
|
|
87
|
-
metadata = metadataLookup.get(currentTarget);
|
|
88
|
-
currentTarget = Reflect.getPrototypeOf(currentTarget);
|
|
89
|
-
}
|
|
90
|
-
metadata = metadata === void 0 ? [] : metadata.slice(0);
|
|
91
|
-
metadataLookup.set(target, metadata);
|
|
92
|
-
}
|
|
93
|
-
return metadata;
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const updateQueue = $global.FAST.getById(1 /* updateQueue */, () => {
|
|
98
|
-
const tasks = [];
|
|
99
|
-
const pendingErrors = [];
|
|
100
|
-
function throwFirstError() {
|
|
101
|
-
if (pendingErrors.length) {
|
|
102
|
-
throw pendingErrors.shift();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function tryRunTask(task) {
|
|
106
|
-
try {
|
|
107
|
-
task.call();
|
|
108
|
-
} catch (error) {
|
|
109
|
-
pendingErrors.push(error);
|
|
110
|
-
setTimeout(throwFirstError, 0);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function process() {
|
|
114
|
-
const capacity = 1024;
|
|
115
|
-
let index = 0;
|
|
116
|
-
while (index < tasks.length) {
|
|
117
|
-
tryRunTask(tasks[index]);
|
|
118
|
-
index++;
|
|
119
|
-
// Prevent leaking memory for long chains of recursive calls to `DOM.queueUpdate`.
|
|
120
|
-
// If we call `DOM.queueUpdate` within a task scheduled by `DOM.queueUpdate`, the queue will
|
|
121
|
-
// grow, but to avoid an O(n) walk for every task we execute, we don't
|
|
122
|
-
// shift tasks off the queue after they have been executed.
|
|
123
|
-
// Instead, we periodically shift 1024 tasks off the queue.
|
|
124
|
-
if (index > capacity) {
|
|
125
|
-
// Manually shift all values starting at the index back to the
|
|
126
|
-
// beginning of the queue.
|
|
127
|
-
for (let scan = 0, newLength = tasks.length - index; scan < newLength; scan++) {
|
|
128
|
-
tasks[scan] = tasks[scan + index];
|
|
129
|
-
}
|
|
130
|
-
tasks.length -= index;
|
|
131
|
-
index = 0;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
tasks.length = 0;
|
|
135
|
-
}
|
|
136
|
-
function enqueue(callable) {
|
|
137
|
-
if (tasks.length < 1) {
|
|
138
|
-
$global.requestAnimationFrame(process);
|
|
139
|
-
}
|
|
140
|
-
tasks.push(callable);
|
|
141
|
-
}
|
|
142
|
-
return Object.freeze({
|
|
143
|
-
enqueue,
|
|
144
|
-
process
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
/* eslint-disable */
|
|
148
|
-
const fastHTMLPolicy = $global.trustedTypes.createPolicy("fast-html", {
|
|
149
|
-
createHTML: html => html
|
|
150
|
-
});
|
|
151
|
-
/* eslint-enable */
|
|
152
|
-
let htmlPolicy = fastHTMLPolicy;
|
|
153
|
-
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
154
|
-
/** @internal */
|
|
155
|
-
const _interpolationStart = `${marker}{`;
|
|
156
|
-
/** @internal */
|
|
157
|
-
const _interpolationEnd = `}${marker}`;
|
|
158
|
-
/**
|
|
159
|
-
* Common DOM APIs.
|
|
160
|
-
* @public
|
|
161
|
-
*/
|
|
162
|
-
const DOM = Object.freeze({
|
|
163
|
-
/**
|
|
164
|
-
* Indicates whether the DOM supports the adoptedStyleSheets feature.
|
|
165
|
-
*/
|
|
166
|
-
supportsAdoptedStyleSheets: Array.isArray(document.adoptedStyleSheets) && "replace" in CSSStyleSheet.prototype,
|
|
167
|
-
/**
|
|
168
|
-
* Sets the HTML trusted types policy used by the templating engine.
|
|
169
|
-
* @param policy - The policy to set for HTML.
|
|
170
|
-
* @remarks
|
|
171
|
-
* This API can only be called once, for security reasons. It should be
|
|
172
|
-
* called by the application developer at the start of their program.
|
|
173
|
-
*/
|
|
174
|
-
setHTMLPolicy(policy) {
|
|
175
|
-
if (htmlPolicy !== fastHTMLPolicy) {
|
|
176
|
-
throw new Error("The HTML policy can only be set once.");
|
|
177
|
-
}
|
|
178
|
-
htmlPolicy = policy;
|
|
179
|
-
},
|
|
180
|
-
/**
|
|
181
|
-
* Turns a string into trusted HTML using the configured trusted types policy.
|
|
182
|
-
* @param html - The string to turn into trusted HTML.
|
|
183
|
-
* @remarks
|
|
184
|
-
* Used internally by the template engine when creating templates
|
|
185
|
-
* and setting innerHTML.
|
|
186
|
-
*/
|
|
187
|
-
createHTML(html) {
|
|
188
|
-
return htmlPolicy.createHTML(html);
|
|
189
|
-
},
|
|
190
|
-
/**
|
|
191
|
-
* Determines if the provided node is a template marker used by the runtime.
|
|
192
|
-
* @param node - The node to test.
|
|
193
|
-
*/
|
|
194
|
-
isMarker(node) {
|
|
195
|
-
return node && node.nodeType === 8 && node.data.startsWith(marker);
|
|
196
|
-
},
|
|
197
|
-
/**
|
|
198
|
-
* Given a marker node, extract the {@link HTMLDirective} index from the placeholder.
|
|
199
|
-
* @param node - The marker node to extract the index from.
|
|
200
|
-
*/
|
|
201
|
-
extractDirectiveIndexFromMarker(node) {
|
|
202
|
-
return parseInt(node.data.replace(`${marker}:`, ""));
|
|
203
|
-
},
|
|
204
|
-
/**
|
|
205
|
-
* Creates a placeholder string suitable for marking out a location *within*
|
|
206
|
-
* an attribute value or HTML content.
|
|
207
|
-
* @param index - The directive index to create the placeholder for.
|
|
208
|
-
* @remarks
|
|
209
|
-
* Used internally by binding directives.
|
|
210
|
-
*/
|
|
211
|
-
createInterpolationPlaceholder(index) {
|
|
212
|
-
return `${_interpolationStart}${index}${_interpolationEnd}`;
|
|
213
|
-
},
|
|
214
|
-
/**
|
|
215
|
-
* Creates a placeholder that manifests itself as an attribute on an
|
|
216
|
-
* element.
|
|
217
|
-
* @param attributeName - The name of the custom attribute.
|
|
218
|
-
* @param index - The directive index to create the placeholder for.
|
|
219
|
-
* @remarks
|
|
220
|
-
* Used internally by attribute directives such as `ref`, `slotted`, and `children`.
|
|
221
|
-
*/
|
|
222
|
-
createCustomAttributePlaceholder(attributeName, index) {
|
|
223
|
-
return `${attributeName}="${this.createInterpolationPlaceholder(index)}"`;
|
|
224
|
-
},
|
|
225
|
-
/**
|
|
226
|
-
* Creates a placeholder that manifests itself as a marker within the DOM structure.
|
|
227
|
-
* @param index - The directive index to create the placeholder for.
|
|
228
|
-
* @remarks
|
|
229
|
-
* Used internally by structural directives such as `repeat`.
|
|
230
|
-
*/
|
|
231
|
-
createBlockPlaceholder(index) {
|
|
232
|
-
return `<!--${marker}:${index}-->`;
|
|
233
|
-
},
|
|
234
|
-
/**
|
|
235
|
-
* Schedules DOM update work in the next async batch.
|
|
236
|
-
* @param callable - The callable function or object to queue.
|
|
237
|
-
*/
|
|
238
|
-
queueUpdate: updateQueue.enqueue,
|
|
239
|
-
/**
|
|
240
|
-
* Immediately processes all work previously scheduled
|
|
241
|
-
* through queueUpdate.
|
|
242
|
-
* @remarks
|
|
243
|
-
* This also forces nextUpdate promises
|
|
244
|
-
* to resolve.
|
|
245
|
-
*/
|
|
246
|
-
processUpdates: updateQueue.process,
|
|
247
|
-
/**
|
|
248
|
-
* Resolves with the next DOM update.
|
|
249
|
-
*/
|
|
250
|
-
nextUpdate() {
|
|
251
|
-
return new Promise(updateQueue.enqueue);
|
|
252
|
-
},
|
|
253
|
-
/**
|
|
254
|
-
* Sets an attribute value on an element.
|
|
255
|
-
* @param element - The element to set the attribute value on.
|
|
256
|
-
* @param attributeName - The attribute name to set.
|
|
257
|
-
* @param value - The value of the attribute to set.
|
|
258
|
-
* @remarks
|
|
259
|
-
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
260
|
-
* it is set to the provided value using the standard `setAttribute` API.
|
|
261
|
-
*/
|
|
262
|
-
setAttribute(element, attributeName, value) {
|
|
263
|
-
if (value === null || value === undefined) {
|
|
264
|
-
element.removeAttribute(attributeName);
|
|
265
|
-
} else {
|
|
266
|
-
element.setAttribute(attributeName, value);
|
|
267
|
-
}
|
|
268
|
-
},
|
|
269
|
-
/**
|
|
270
|
-
* Sets a boolean attribute value.
|
|
271
|
-
* @param element - The element to set the boolean attribute value on.
|
|
272
|
-
* @param attributeName - The attribute name to set.
|
|
273
|
-
* @param value - The value of the attribute to set.
|
|
274
|
-
* @remarks
|
|
275
|
-
* If the value is true, the attribute is added; otherwise it is removed.
|
|
276
|
-
*/
|
|
277
|
-
setBooleanAttribute(element, attributeName, value) {
|
|
278
|
-
value ? element.setAttribute(attributeName, "") : element.removeAttribute(attributeName);
|
|
279
|
-
},
|
|
280
|
-
/**
|
|
281
|
-
* Removes all the child nodes of the provided parent node.
|
|
282
|
-
* @param parent - The node to remove the children from.
|
|
283
|
-
*/
|
|
284
|
-
removeChildNodes(parent) {
|
|
285
|
-
for (let child = parent.firstChild; child !== null; child = parent.firstChild) {
|
|
286
|
-
parent.removeChild(child);
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
/**
|
|
290
|
-
* Creates a TreeWalker configured to walk a template fragment.
|
|
291
|
-
* @param fragment - The fragment to walk.
|
|
292
|
-
*/
|
|
293
|
-
createTemplateWalker(fragment) {
|
|
294
|
-
return document.createTreeWalker(fragment, 133,
|
|
295
|
-
// element, text, comment
|
|
296
|
-
null, false);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* An implementation of {@link Notifier} that efficiently keeps track of
|
|
302
|
-
* subscribers interested in a specific change notification on an
|
|
303
|
-
* observable source.
|
|
304
|
-
*
|
|
305
|
-
* @remarks
|
|
306
|
-
* This set is optimized for the most common scenario of 1 or 2 subscribers.
|
|
307
|
-
* With this in mind, it can store a subscriber in an internal field, allowing it to avoid Array#push operations.
|
|
308
|
-
* If the set ever exceeds two subscribers, it upgrades to an array automatically.
|
|
309
|
-
* @public
|
|
310
|
-
*/
|
|
311
|
-
class SubscriberSet {
|
|
312
|
-
/**
|
|
313
|
-
* Creates an instance of SubscriberSet for the specified source.
|
|
314
|
-
* @param source - The object source that subscribers will receive notifications from.
|
|
315
|
-
* @param initialSubscriber - An initial subscriber to changes.
|
|
316
|
-
*/
|
|
317
|
-
constructor(source, initialSubscriber) {
|
|
318
|
-
this.sub1 = void 0;
|
|
319
|
-
this.sub2 = void 0;
|
|
320
|
-
this.spillover = void 0;
|
|
321
|
-
this.source = source;
|
|
322
|
-
this.sub1 = initialSubscriber;
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Checks whether the provided subscriber has been added to this set.
|
|
326
|
-
* @param subscriber - The subscriber to test for inclusion in this set.
|
|
327
|
-
*/
|
|
328
|
-
has(subscriber) {
|
|
329
|
-
return this.spillover === void 0 ? this.sub1 === subscriber || this.sub2 === subscriber : this.spillover.indexOf(subscriber) !== -1;
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Subscribes to notification of changes in an object's state.
|
|
333
|
-
* @param subscriber - The object that is subscribing for change notification.
|
|
334
|
-
*/
|
|
335
|
-
subscribe(subscriber) {
|
|
336
|
-
const spillover = this.spillover;
|
|
337
|
-
if (spillover === void 0) {
|
|
338
|
-
if (this.has(subscriber)) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
if (this.sub1 === void 0) {
|
|
342
|
-
this.sub1 = subscriber;
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (this.sub2 === void 0) {
|
|
346
|
-
this.sub2 = subscriber;
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
this.spillover = [this.sub1, this.sub2, subscriber];
|
|
350
|
-
this.sub1 = void 0;
|
|
351
|
-
this.sub2 = void 0;
|
|
352
|
-
} else {
|
|
353
|
-
const index = spillover.indexOf(subscriber);
|
|
354
|
-
if (index === -1) {
|
|
355
|
-
spillover.push(subscriber);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Unsubscribes from notification of changes in an object's state.
|
|
361
|
-
* @param subscriber - The object that is unsubscribing from change notification.
|
|
362
|
-
*/
|
|
363
|
-
unsubscribe(subscriber) {
|
|
364
|
-
const spillover = this.spillover;
|
|
365
|
-
if (spillover === void 0) {
|
|
366
|
-
if (this.sub1 === subscriber) {
|
|
367
|
-
this.sub1 = void 0;
|
|
368
|
-
} else if (this.sub2 === subscriber) {
|
|
369
|
-
this.sub2 = void 0;
|
|
370
|
-
}
|
|
371
|
-
} else {
|
|
372
|
-
const index = spillover.indexOf(subscriber);
|
|
373
|
-
if (index !== -1) {
|
|
374
|
-
spillover.splice(index, 1);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Notifies all subscribers.
|
|
380
|
-
* @param args - Data passed along to subscribers during notification.
|
|
381
|
-
*/
|
|
382
|
-
notify(args) {
|
|
383
|
-
const spillover = this.spillover;
|
|
384
|
-
const source = this.source;
|
|
385
|
-
if (spillover === void 0) {
|
|
386
|
-
const sub1 = this.sub1;
|
|
387
|
-
const sub2 = this.sub2;
|
|
388
|
-
if (sub1 !== void 0) {
|
|
389
|
-
sub1.handleChange(source, args);
|
|
390
|
-
}
|
|
391
|
-
if (sub2 !== void 0) {
|
|
392
|
-
sub2.handleChange(source, args);
|
|
393
|
-
}
|
|
394
|
-
} else {
|
|
395
|
-
for (let i = 0, ii = spillover.length; i < ii; ++i) {
|
|
396
|
-
spillover[i].handleChange(source, args);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* An implementation of Notifier that allows subscribers to be notified
|
|
403
|
-
* of individual property changes on an object.
|
|
404
|
-
* @public
|
|
405
|
-
*/
|
|
406
|
-
class PropertyChangeNotifier {
|
|
407
|
-
/**
|
|
408
|
-
* Creates an instance of PropertyChangeNotifier for the specified source.
|
|
409
|
-
* @param source - The object source that subscribers will receive notifications from.
|
|
410
|
-
*/
|
|
411
|
-
constructor(source) {
|
|
412
|
-
this.subscribers = {};
|
|
413
|
-
this.sourceSubscribers = null;
|
|
414
|
-
this.source = source;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Notifies all subscribers, based on the specified property.
|
|
418
|
-
* @param propertyName - The property name, passed along to subscribers during notification.
|
|
419
|
-
*/
|
|
420
|
-
notify(propertyName) {
|
|
421
|
-
var _a;
|
|
422
|
-
const subscribers = this.subscribers[propertyName];
|
|
423
|
-
if (subscribers !== void 0) {
|
|
424
|
-
subscribers.notify(propertyName);
|
|
425
|
-
}
|
|
426
|
-
(_a = this.sourceSubscribers) === null || _a === void 0 ? void 0 : _a.notify(propertyName);
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Subscribes to notification of changes in an object's state.
|
|
430
|
-
* @param subscriber - The object that is subscribing for change notification.
|
|
431
|
-
* @param propertyToWatch - The name of the property that the subscriber is interested in watching for changes.
|
|
432
|
-
*/
|
|
433
|
-
subscribe(subscriber, propertyToWatch) {
|
|
434
|
-
var _a;
|
|
435
|
-
if (propertyToWatch) {
|
|
436
|
-
let subscribers = this.subscribers[propertyToWatch];
|
|
437
|
-
if (subscribers === void 0) {
|
|
438
|
-
this.subscribers[propertyToWatch] = subscribers = new SubscriberSet(this.source);
|
|
439
|
-
}
|
|
440
|
-
subscribers.subscribe(subscriber);
|
|
441
|
-
} else {
|
|
442
|
-
this.sourceSubscribers = (_a = this.sourceSubscribers) !== null && _a !== void 0 ? _a : new SubscriberSet(this.source);
|
|
443
|
-
this.sourceSubscribers.subscribe(subscriber);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Unsubscribes from notification of changes in an object's state.
|
|
448
|
-
* @param subscriber - The object that is unsubscribing from change notification.
|
|
449
|
-
* @param propertyToUnwatch - The name of the property that the subscriber is no longer interested in watching.
|
|
450
|
-
*/
|
|
451
|
-
unsubscribe(subscriber, propertyToUnwatch) {
|
|
452
|
-
var _a;
|
|
453
|
-
if (propertyToUnwatch) {
|
|
454
|
-
const subscribers = this.subscribers[propertyToUnwatch];
|
|
455
|
-
if (subscribers !== void 0) {
|
|
456
|
-
subscribers.unsubscribe(subscriber);
|
|
457
|
-
}
|
|
458
|
-
} else {
|
|
459
|
-
(_a = this.sourceSubscribers) === null || _a === void 0 ? void 0 : _a.unsubscribe(subscriber);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Common Observable APIs.
|
|
466
|
-
* @public
|
|
467
|
-
*/
|
|
468
|
-
const Observable = FAST.getById(2 /* observable */, () => {
|
|
469
|
-
const volatileRegex = /(:|&&|\|\||if)/;
|
|
470
|
-
const notifierLookup = new WeakMap();
|
|
471
|
-
const queueUpdate = DOM.queueUpdate;
|
|
472
|
-
let watcher = void 0;
|
|
473
|
-
let createArrayObserver = array => {
|
|
474
|
-
throw new Error("Must call enableArrayObservation before observing arrays.");
|
|
475
|
-
};
|
|
476
|
-
function getNotifier(source) {
|
|
477
|
-
let found = source.$fastController || notifierLookup.get(source);
|
|
478
|
-
if (found === void 0) {
|
|
479
|
-
if (Array.isArray(source)) {
|
|
480
|
-
found = createArrayObserver(source);
|
|
481
|
-
} else {
|
|
482
|
-
notifierLookup.set(source, found = new PropertyChangeNotifier(source));
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return found;
|
|
486
|
-
}
|
|
487
|
-
const getAccessors = createMetadataLocator();
|
|
488
|
-
class DefaultObservableAccessor {
|
|
489
|
-
constructor(name) {
|
|
490
|
-
this.name = name;
|
|
491
|
-
this.field = `_${name}`;
|
|
492
|
-
this.callback = `${name}Changed`;
|
|
493
|
-
}
|
|
494
|
-
getValue(source) {
|
|
495
|
-
if (watcher !== void 0) {
|
|
496
|
-
watcher.watch(source, this.name);
|
|
497
|
-
}
|
|
498
|
-
return source[this.field];
|
|
499
|
-
}
|
|
500
|
-
setValue(source, newValue) {
|
|
501
|
-
const field = this.field;
|
|
502
|
-
const oldValue = source[field];
|
|
503
|
-
if (oldValue !== newValue) {
|
|
504
|
-
source[field] = newValue;
|
|
505
|
-
const callback = source[this.callback];
|
|
506
|
-
if (typeof callback === "function") {
|
|
507
|
-
callback.call(source, oldValue, newValue);
|
|
508
|
-
}
|
|
509
|
-
getNotifier(source).notify(this.name);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
class BindingObserverImplementation extends SubscriberSet {
|
|
514
|
-
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
515
|
-
super(binding, initialSubscriber);
|
|
516
|
-
this.binding = binding;
|
|
517
|
-
this.isVolatileBinding = isVolatileBinding;
|
|
518
|
-
this.needsRefresh = true;
|
|
519
|
-
this.needsQueue = true;
|
|
520
|
-
this.first = this;
|
|
521
|
-
this.last = null;
|
|
522
|
-
this.propertySource = void 0;
|
|
523
|
-
this.propertyName = void 0;
|
|
524
|
-
this.notifier = void 0;
|
|
525
|
-
this.next = void 0;
|
|
526
|
-
}
|
|
527
|
-
observe(source, context) {
|
|
528
|
-
if (this.needsRefresh && this.last !== null) {
|
|
529
|
-
this.disconnect();
|
|
530
|
-
}
|
|
531
|
-
const previousWatcher = watcher;
|
|
532
|
-
watcher = this.needsRefresh ? this : void 0;
|
|
533
|
-
this.needsRefresh = this.isVolatileBinding;
|
|
534
|
-
const result = this.binding(source, context);
|
|
535
|
-
watcher = previousWatcher;
|
|
536
|
-
return result;
|
|
537
|
-
}
|
|
538
|
-
disconnect() {
|
|
539
|
-
if (this.last !== null) {
|
|
540
|
-
let current = this.first;
|
|
541
|
-
while (current !== void 0) {
|
|
542
|
-
current.notifier.unsubscribe(this, current.propertyName);
|
|
543
|
-
current = current.next;
|
|
544
|
-
}
|
|
545
|
-
this.last = null;
|
|
546
|
-
this.needsRefresh = this.needsQueue = true;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
watch(propertySource, propertyName) {
|
|
550
|
-
const prev = this.last;
|
|
551
|
-
const notifier = getNotifier(propertySource);
|
|
552
|
-
const current = prev === null ? this.first : {};
|
|
553
|
-
current.propertySource = propertySource;
|
|
554
|
-
current.propertyName = propertyName;
|
|
555
|
-
current.notifier = notifier;
|
|
556
|
-
notifier.subscribe(this, propertyName);
|
|
557
|
-
if (prev !== null) {
|
|
558
|
-
if (!this.needsRefresh) {
|
|
559
|
-
// Declaring the variable prior to assignment below circumvents
|
|
560
|
-
// a bug in Angular's optimization process causing infinite recursion
|
|
561
|
-
// of this watch() method. Details https://github.com/microsoft/fast/issues/4969
|
|
562
|
-
let prevValue;
|
|
563
|
-
watcher = void 0;
|
|
564
|
-
/* eslint-disable-next-line */
|
|
565
|
-
prevValue = prev.propertySource[prev.propertyName];
|
|
566
|
-
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
|
|
567
|
-
watcher = this;
|
|
568
|
-
if (propertySource === prevValue) {
|
|
569
|
-
this.needsRefresh = true;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
prev.next = current;
|
|
573
|
-
}
|
|
574
|
-
this.last = current;
|
|
575
|
-
}
|
|
576
|
-
handleChange() {
|
|
577
|
-
if (this.needsQueue) {
|
|
578
|
-
this.needsQueue = false;
|
|
579
|
-
queueUpdate(this);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
call() {
|
|
583
|
-
if (this.last !== null) {
|
|
584
|
-
this.needsQueue = true;
|
|
585
|
-
this.notify(this);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
records() {
|
|
589
|
-
let next = this.first;
|
|
590
|
-
return {
|
|
591
|
-
next: () => {
|
|
592
|
-
const current = next;
|
|
593
|
-
if (current === undefined) {
|
|
594
|
-
return {
|
|
595
|
-
value: void 0,
|
|
596
|
-
done: true
|
|
597
|
-
};
|
|
598
|
-
} else {
|
|
599
|
-
next = next.next;
|
|
600
|
-
return {
|
|
601
|
-
value: current,
|
|
602
|
-
done: false
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
},
|
|
606
|
-
[Symbol.iterator]: function () {
|
|
607
|
-
return this;
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return Object.freeze({
|
|
613
|
-
/**
|
|
614
|
-
* @internal
|
|
615
|
-
* @param factory - The factory used to create array observers.
|
|
616
|
-
*/
|
|
617
|
-
setArrayObserverFactory(factory) {
|
|
618
|
-
createArrayObserver = factory;
|
|
619
|
-
},
|
|
620
|
-
/**
|
|
621
|
-
* Gets a notifier for an object or Array.
|
|
622
|
-
* @param source - The object or Array to get the notifier for.
|
|
623
|
-
*/
|
|
624
|
-
getNotifier,
|
|
625
|
-
/**
|
|
626
|
-
* Records a property change for a source object.
|
|
627
|
-
* @param source - The object to record the change against.
|
|
628
|
-
* @param propertyName - The property to track as changed.
|
|
629
|
-
*/
|
|
630
|
-
track(source, propertyName) {
|
|
631
|
-
if (watcher !== void 0) {
|
|
632
|
-
watcher.watch(source, propertyName);
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
/**
|
|
636
|
-
* Notifies watchers that the currently executing property getter or function is volatile
|
|
637
|
-
* with respect to its observable dependencies.
|
|
638
|
-
*/
|
|
639
|
-
trackVolatile() {
|
|
640
|
-
if (watcher !== void 0) {
|
|
641
|
-
watcher.needsRefresh = true;
|
|
642
|
-
}
|
|
643
|
-
},
|
|
644
|
-
/**
|
|
645
|
-
* Notifies subscribers of a source object of changes.
|
|
646
|
-
* @param source - the object to notify of changes.
|
|
647
|
-
* @param args - The change args to pass to subscribers.
|
|
648
|
-
*/
|
|
649
|
-
notify(source, args) {
|
|
650
|
-
getNotifier(source).notify(args);
|
|
651
|
-
},
|
|
652
|
-
/**
|
|
653
|
-
* Defines an observable property on an object or prototype.
|
|
654
|
-
* @param target - The target object to define the observable on.
|
|
655
|
-
* @param nameOrAccessor - The name of the property to define as observable;
|
|
656
|
-
* or a custom accessor that specifies the property name and accessor implementation.
|
|
657
|
-
*/
|
|
658
|
-
defineProperty(target, nameOrAccessor) {
|
|
659
|
-
if (typeof nameOrAccessor === "string") {
|
|
660
|
-
nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
|
|
661
|
-
}
|
|
662
|
-
getAccessors(target).push(nameOrAccessor);
|
|
663
|
-
Reflect.defineProperty(target, nameOrAccessor.name, {
|
|
664
|
-
enumerable: true,
|
|
665
|
-
get: function () {
|
|
666
|
-
return nameOrAccessor.getValue(this);
|
|
667
|
-
},
|
|
668
|
-
set: function (newValue) {
|
|
669
|
-
nameOrAccessor.setValue(this, newValue);
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
},
|
|
673
|
-
/**
|
|
674
|
-
* Finds all the observable accessors defined on the target,
|
|
675
|
-
* including its prototype chain.
|
|
676
|
-
* @param target - The target object to search for accessor on.
|
|
677
|
-
*/
|
|
678
|
-
getAccessors,
|
|
679
|
-
/**
|
|
680
|
-
* Creates a {@link BindingObserver} that can watch the
|
|
681
|
-
* provided {@link Binding} for changes.
|
|
682
|
-
* @param binding - The binding to observe.
|
|
683
|
-
* @param initialSubscriber - An initial subscriber to changes in the binding value.
|
|
684
|
-
* @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
|
|
685
|
-
*/
|
|
686
|
-
binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
|
|
687
|
-
return new BindingObserverImplementation(binding, initialSubscriber, isVolatileBinding);
|
|
688
|
-
},
|
|
689
|
-
/**
|
|
690
|
-
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
691
|
-
* on every evaluation of the value.
|
|
692
|
-
* @param binding - The binding to inspect.
|
|
693
|
-
*/
|
|
694
|
-
isVolatileBinding(binding) {
|
|
695
|
-
return volatileRegex.test(binding.toString());
|
|
696
|
-
}
|
|
697
|
-
});
|
|
698
|
-
});
|
|
699
|
-
const contextEvent = FAST.getById(3 /* contextEvent */, () => {
|
|
700
|
-
let current = null;
|
|
701
|
-
return {
|
|
702
|
-
get() {
|
|
703
|
-
return current;
|
|
704
|
-
},
|
|
705
|
-
set(event) {
|
|
706
|
-
current = event;
|
|
707
|
-
}
|
|
708
|
-
};
|
|
709
|
-
});
|
|
710
|
-
/**
|
|
711
|
-
* Provides additional contextual information available to behaviors and expressions.
|
|
712
|
-
* @public
|
|
713
|
-
*/
|
|
714
|
-
class ExecutionContext {
|
|
715
|
-
constructor() {
|
|
716
|
-
/**
|
|
717
|
-
* The index of the current item within a repeat context.
|
|
718
|
-
*/
|
|
719
|
-
this.index = 0;
|
|
720
|
-
/**
|
|
721
|
-
* The length of the current collection within a repeat context.
|
|
722
|
-
*/
|
|
723
|
-
this.length = 0;
|
|
724
|
-
/**
|
|
725
|
-
* The parent data object within a repeat context.
|
|
726
|
-
*/
|
|
727
|
-
this.parent = null;
|
|
728
|
-
/**
|
|
729
|
-
* The parent execution context when in nested context scenarios.
|
|
730
|
-
*/
|
|
731
|
-
this.parentContext = null;
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* The current event within an event handler.
|
|
735
|
-
*/
|
|
736
|
-
get event() {
|
|
737
|
-
return contextEvent.get();
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Indicates whether the current item within a repeat context
|
|
741
|
-
* has an even index.
|
|
742
|
-
*/
|
|
743
|
-
get isEven() {
|
|
744
|
-
return this.index % 2 === 0;
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
* Indicates whether the current item within a repeat context
|
|
748
|
-
* has an odd index.
|
|
749
|
-
*/
|
|
750
|
-
get isOdd() {
|
|
751
|
-
return this.index % 2 !== 0;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Indicates whether the current item within a repeat context
|
|
755
|
-
* is the first item in the collection.
|
|
756
|
-
*/
|
|
757
|
-
get isFirst() {
|
|
758
|
-
return this.index === 0;
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Indicates whether the current item within a repeat context
|
|
762
|
-
* is somewhere in the middle of the collection.
|
|
763
|
-
*/
|
|
764
|
-
get isInMiddle() {
|
|
765
|
-
return !this.isFirst && !this.isLast;
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Indicates whether the current item within a repeat context
|
|
769
|
-
* is the last item in the collection.
|
|
770
|
-
*/
|
|
771
|
-
get isLast() {
|
|
772
|
-
return this.index === this.length - 1;
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* Sets the event for the current execution context.
|
|
776
|
-
* @param event - The event to set.
|
|
777
|
-
* @internal
|
|
778
|
-
*/
|
|
779
|
-
static setEvent(event) {
|
|
780
|
-
contextEvent.set(event);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
Observable.defineProperty(ExecutionContext.prototype, "index");
|
|
784
|
-
Observable.defineProperty(ExecutionContext.prototype, "length");
|
|
785
|
-
/**
|
|
786
|
-
* The default execution context used in binding expressions.
|
|
787
|
-
* @public
|
|
788
|
-
*/
|
|
789
|
-
const defaultExecutionContext = Object.seal(new ExecutionContext());
|
|
790
|
-
|
|
791
|
-
/**
|
|
792
|
-
* Represents styles that can be applied to a custom element.
|
|
793
|
-
* @public
|
|
794
|
-
*/
|
|
795
|
-
class ElementStyles {
|
|
796
|
-
constructor() {
|
|
797
|
-
this.targets = new WeakSet();
|
|
798
|
-
}
|
|
799
|
-
/** @internal */
|
|
800
|
-
addStylesTo(target) {
|
|
801
|
-
this.targets.add(target);
|
|
802
|
-
}
|
|
803
|
-
/** @internal */
|
|
804
|
-
removeStylesFrom(target) {
|
|
805
|
-
this.targets.delete(target);
|
|
806
|
-
}
|
|
807
|
-
/** @internal */
|
|
808
|
-
isAttachedTo(target) {
|
|
809
|
-
return this.targets.has(target);
|
|
810
|
-
}
|
|
811
|
-
/**
|
|
812
|
-
* Associates behaviors with this set of styles.
|
|
813
|
-
* @param behaviors - The behaviors to associate.
|
|
814
|
-
*/
|
|
815
|
-
withBehaviors(...behaviors) {
|
|
816
|
-
this.behaviors = this.behaviors === null ? behaviors : this.behaviors.concat(behaviors);
|
|
817
|
-
return this;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
/**
|
|
821
|
-
* Create ElementStyles from ComposableStyles.
|
|
822
|
-
*/
|
|
823
|
-
ElementStyles.create = (() => {
|
|
824
|
-
if (DOM.supportsAdoptedStyleSheets) {
|
|
825
|
-
const styleSheetCache = new Map();
|
|
826
|
-
return styles =>
|
|
827
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
828
|
-
new AdoptedStyleSheetsStyles(styles, styleSheetCache);
|
|
829
|
-
}
|
|
830
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
831
|
-
return styles => new StyleElementStyles(styles);
|
|
832
|
-
})();
|
|
833
|
-
function reduceStyles(styles) {
|
|
834
|
-
return styles.map(x => x instanceof ElementStyles ? reduceStyles(x.styles) : [x]).reduce((prev, curr) => prev.concat(curr), []);
|
|
835
|
-
}
|
|
836
|
-
function reduceBehaviors(styles) {
|
|
837
|
-
return styles.map(x => x instanceof ElementStyles ? x.behaviors : null).reduce((prev, curr) => {
|
|
838
|
-
if (curr === null) {
|
|
839
|
-
return prev;
|
|
840
|
-
}
|
|
841
|
-
if (prev === null) {
|
|
842
|
-
prev = [];
|
|
843
|
-
}
|
|
844
|
-
return prev.concat(curr);
|
|
845
|
-
}, null);
|
|
846
|
-
}
|
|
847
|
-
/**
|
|
848
|
-
* https://wicg.github.io/construct-stylesheets/
|
|
849
|
-
* https://developers.google.com/web/updates/2019/02/constructable-stylesheets
|
|
850
|
-
*
|
|
851
|
-
* @internal
|
|
852
|
-
*/
|
|
853
|
-
class AdoptedStyleSheetsStyles extends ElementStyles {
|
|
854
|
-
constructor(styles, styleSheetCache) {
|
|
855
|
-
super();
|
|
856
|
-
this.styles = styles;
|
|
857
|
-
this.styleSheetCache = styleSheetCache;
|
|
858
|
-
this._styleSheets = void 0;
|
|
859
|
-
this.behaviors = reduceBehaviors(styles);
|
|
860
|
-
}
|
|
861
|
-
get styleSheets() {
|
|
862
|
-
if (this._styleSheets === void 0) {
|
|
863
|
-
const styles = this.styles;
|
|
864
|
-
const styleSheetCache = this.styleSheetCache;
|
|
865
|
-
this._styleSheets = reduceStyles(styles).map(x => {
|
|
866
|
-
if (x instanceof CSSStyleSheet) {
|
|
867
|
-
return x;
|
|
868
|
-
}
|
|
869
|
-
let sheet = styleSheetCache.get(x);
|
|
870
|
-
if (sheet === void 0) {
|
|
871
|
-
sheet = new CSSStyleSheet();
|
|
872
|
-
sheet.replaceSync(x);
|
|
873
|
-
styleSheetCache.set(x, sheet);
|
|
874
|
-
}
|
|
875
|
-
return sheet;
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
return this._styleSheets;
|
|
879
|
-
}
|
|
880
|
-
addStylesTo(target) {
|
|
881
|
-
target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.styleSheets];
|
|
882
|
-
super.addStylesTo(target);
|
|
883
|
-
}
|
|
884
|
-
removeStylesFrom(target) {
|
|
885
|
-
const sourceSheets = this.styleSheets;
|
|
886
|
-
target.adoptedStyleSheets = target.adoptedStyleSheets.filter(x => sourceSheets.indexOf(x) === -1);
|
|
887
|
-
super.removeStylesFrom(target);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
let styleClassId = 0;
|
|
891
|
-
function getNextStyleClass() {
|
|
892
|
-
return `fast-style-class-${++styleClassId}`;
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* @internal
|
|
896
|
-
*/
|
|
897
|
-
class StyleElementStyles extends ElementStyles {
|
|
898
|
-
constructor(styles) {
|
|
899
|
-
super();
|
|
900
|
-
this.styles = styles;
|
|
901
|
-
this.behaviors = null;
|
|
902
|
-
this.behaviors = reduceBehaviors(styles);
|
|
903
|
-
this.styleSheets = reduceStyles(styles);
|
|
904
|
-
this.styleClass = getNextStyleClass();
|
|
905
|
-
}
|
|
906
|
-
addStylesTo(target) {
|
|
907
|
-
const styleSheets = this.styleSheets;
|
|
908
|
-
const styleClass = this.styleClass;
|
|
909
|
-
target = this.normalizeTarget(target);
|
|
910
|
-
for (let i = 0; i < styleSheets.length; i++) {
|
|
911
|
-
const element = document.createElement("style");
|
|
912
|
-
element.innerHTML = styleSheets[i];
|
|
913
|
-
element.className = styleClass;
|
|
914
|
-
target.append(element);
|
|
915
|
-
}
|
|
916
|
-
super.addStylesTo(target);
|
|
917
|
-
}
|
|
918
|
-
removeStylesFrom(target) {
|
|
919
|
-
target = this.normalizeTarget(target);
|
|
920
|
-
const styles = target.querySelectorAll(`.${this.styleClass}`);
|
|
921
|
-
for (let i = 0, ii = styles.length; i < ii; ++i) {
|
|
922
|
-
target.removeChild(styles[i]);
|
|
923
|
-
}
|
|
924
|
-
super.removeStylesFrom(target);
|
|
925
|
-
}
|
|
926
|
-
isAttachedTo(target) {
|
|
927
|
-
return super.isAttachedTo(this.normalizeTarget(target));
|
|
928
|
-
}
|
|
929
|
-
normalizeTarget(target) {
|
|
930
|
-
return target === document ? document.body : target;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
/**
|
|
935
|
-
* Metadata used to configure a custom attribute's behavior.
|
|
936
|
-
* @public
|
|
937
|
-
*/
|
|
938
|
-
const AttributeConfiguration = Object.freeze({
|
|
939
|
-
/**
|
|
940
|
-
* Locates all attribute configurations associated with a type.
|
|
941
|
-
*/
|
|
942
|
-
locate: createMetadataLocator()
|
|
943
|
-
});
|
|
944
|
-
/**
|
|
945
|
-
* A {@link ValueConverter} that converts to and from `boolean` values.
|
|
946
|
-
* @remarks
|
|
947
|
-
* Used automatically when the `boolean` {@link AttributeMode} is selected.
|
|
948
|
-
* @public
|
|
949
|
-
*/
|
|
950
|
-
const booleanConverter = {
|
|
951
|
-
toView(value) {
|
|
952
|
-
return value ? "true" : "false";
|
|
953
|
-
},
|
|
954
|
-
fromView(value) {
|
|
955
|
-
if (value === null || value === void 0 || value === "false" || value === false || value === 0) {
|
|
956
|
-
return false;
|
|
957
|
-
}
|
|
958
|
-
return true;
|
|
959
|
-
}
|
|
960
|
-
};
|
|
961
|
-
/**
|
|
962
|
-
* An implementation of {@link Accessor} that supports reactivity,
|
|
963
|
-
* change callbacks, attribute reflection, and type conversion for
|
|
964
|
-
* custom elements.
|
|
965
|
-
* @public
|
|
966
|
-
*/
|
|
967
|
-
class AttributeDefinition {
|
|
968
|
-
/**
|
|
969
|
-
* Creates an instance of AttributeDefinition.
|
|
970
|
-
* @param Owner - The class constructor that owns this attribute.
|
|
971
|
-
* @param name - The name of the property associated with the attribute.
|
|
972
|
-
* @param attribute - The name of the attribute in HTML.
|
|
973
|
-
* @param mode - The {@link AttributeMode} that describes the behavior of this attribute.
|
|
974
|
-
* @param converter - A {@link ValueConverter} that integrates with the property getter/setter
|
|
975
|
-
* to convert values to and from a DOM string.
|
|
976
|
-
*/
|
|
977
|
-
constructor(Owner, name, attribute = name.toLowerCase(), mode = "reflect", converter) {
|
|
978
|
-
this.guards = new Set();
|
|
979
|
-
this.Owner = Owner;
|
|
980
|
-
this.name = name;
|
|
981
|
-
this.attribute = attribute;
|
|
982
|
-
this.mode = mode;
|
|
983
|
-
this.converter = converter;
|
|
984
|
-
this.fieldName = `_${name}`;
|
|
985
|
-
this.callbackName = `${name}Changed`;
|
|
986
|
-
this.hasCallback = this.callbackName in Owner.prototype;
|
|
987
|
-
if (mode === "boolean" && converter === void 0) {
|
|
988
|
-
this.converter = booleanConverter;
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
/**
|
|
992
|
-
* Sets the value of the attribute/property on the source element.
|
|
993
|
-
* @param source - The source element to access.
|
|
994
|
-
* @param value - The value to set the attribute/property to.
|
|
995
|
-
*/
|
|
996
|
-
setValue(source, newValue) {
|
|
997
|
-
const oldValue = source[this.fieldName];
|
|
998
|
-
const converter = this.converter;
|
|
999
|
-
if (converter !== void 0) {
|
|
1000
|
-
newValue = converter.fromView(newValue);
|
|
1001
|
-
}
|
|
1002
|
-
if (oldValue !== newValue) {
|
|
1003
|
-
source[this.fieldName] = newValue;
|
|
1004
|
-
this.tryReflectToAttribute(source);
|
|
1005
|
-
if (this.hasCallback) {
|
|
1006
|
-
source[this.callbackName](oldValue, newValue);
|
|
1007
|
-
}
|
|
1008
|
-
source.$fastController.notify(this.name);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Gets the value of the attribute/property on the source element.
|
|
1013
|
-
* @param source - The source element to access.
|
|
1014
|
-
*/
|
|
1015
|
-
getValue(source) {
|
|
1016
|
-
Observable.track(source, this.name);
|
|
1017
|
-
return source[this.fieldName];
|
|
1018
|
-
}
|
|
1019
|
-
/** @internal */
|
|
1020
|
-
onAttributeChangedCallback(element, value) {
|
|
1021
|
-
if (this.guards.has(element)) {
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
this.guards.add(element);
|
|
1025
|
-
this.setValue(element, value);
|
|
1026
|
-
this.guards.delete(element);
|
|
1027
|
-
}
|
|
1028
|
-
tryReflectToAttribute(element) {
|
|
1029
|
-
const mode = this.mode;
|
|
1030
|
-
const guards = this.guards;
|
|
1031
|
-
if (guards.has(element) || mode === "fromView") {
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
DOM.queueUpdate(() => {
|
|
1035
|
-
guards.add(element);
|
|
1036
|
-
const latestValue = element[this.fieldName];
|
|
1037
|
-
switch (mode) {
|
|
1038
|
-
case "reflect":
|
|
1039
|
-
const converter = this.converter;
|
|
1040
|
-
DOM.setAttribute(element, this.attribute, converter !== void 0 ? converter.toView(latestValue) : latestValue);
|
|
1041
|
-
break;
|
|
1042
|
-
case "boolean":
|
|
1043
|
-
DOM.setBooleanAttribute(element, this.attribute, latestValue);
|
|
1044
|
-
break;
|
|
1045
|
-
}
|
|
1046
|
-
guards.delete(element);
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Collects all attribute definitions associated with the owner.
|
|
1051
|
-
* @param Owner - The class constructor to collect attribute for.
|
|
1052
|
-
* @param attributeLists - Any existing attributes to collect and merge with those associated with the owner.
|
|
1053
|
-
* @internal
|
|
1054
|
-
*/
|
|
1055
|
-
static collect(Owner, ...attributeLists) {
|
|
1056
|
-
const attributes = [];
|
|
1057
|
-
attributeLists.push(AttributeConfiguration.locate(Owner));
|
|
1058
|
-
for (let i = 0, ii = attributeLists.length; i < ii; ++i) {
|
|
1059
|
-
const list = attributeLists[i];
|
|
1060
|
-
if (list === void 0) {
|
|
1061
|
-
continue;
|
|
1062
|
-
}
|
|
1063
|
-
for (let j = 0, jj = list.length; j < jj; ++j) {
|
|
1064
|
-
const config = list[j];
|
|
1065
|
-
if (typeof config === "string") {
|
|
1066
|
-
attributes.push(new AttributeDefinition(Owner, config));
|
|
1067
|
-
} else {
|
|
1068
|
-
attributes.push(new AttributeDefinition(Owner, config.property, config.attribute, config.mode, config.converter));
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
return attributes;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
const defaultShadowOptions = {
|
|
1077
|
-
mode: "open"
|
|
1078
|
-
};
|
|
1079
|
-
const defaultElementOptions = {};
|
|
1080
|
-
const fastRegistry = FAST.getById(4 /* elementRegistry */, () => {
|
|
1081
|
-
const typeToDefinition = new Map();
|
|
1082
|
-
return Object.freeze({
|
|
1083
|
-
register(definition) {
|
|
1084
|
-
if (typeToDefinition.has(definition.type)) {
|
|
1085
|
-
return false;
|
|
1086
|
-
}
|
|
1087
|
-
typeToDefinition.set(definition.type, definition);
|
|
1088
|
-
return true;
|
|
1089
|
-
},
|
|
1090
|
-
getByType(key) {
|
|
1091
|
-
return typeToDefinition.get(key);
|
|
1092
|
-
}
|
|
1093
|
-
});
|
|
1094
|
-
});
|
|
1095
|
-
/**
|
|
1096
|
-
* Defines metadata for a FASTElement.
|
|
1097
|
-
* @public
|
|
1098
|
-
*/
|
|
1099
|
-
class FASTElementDefinition {
|
|
1100
|
-
/**
|
|
1101
|
-
* Creates an instance of FASTElementDefinition.
|
|
1102
|
-
* @param type - The type this definition is being created for.
|
|
1103
|
-
* @param nameOrConfig - The name of the element to define or a config object
|
|
1104
|
-
* that describes the element to define.
|
|
1105
|
-
*/
|
|
1106
|
-
constructor(type, nameOrConfig = type.definition) {
|
|
1107
|
-
if (typeof nameOrConfig === "string") {
|
|
1108
|
-
nameOrConfig = {
|
|
1109
|
-
name: nameOrConfig
|
|
1110
|
-
};
|
|
1111
|
-
}
|
|
1112
|
-
this.type = type;
|
|
1113
|
-
this.name = nameOrConfig.name;
|
|
1114
|
-
this.template = nameOrConfig.template;
|
|
1115
|
-
const attributes = AttributeDefinition.collect(type, nameOrConfig.attributes);
|
|
1116
|
-
const observedAttributes = new Array(attributes.length);
|
|
1117
|
-
const propertyLookup = {};
|
|
1118
|
-
const attributeLookup = {};
|
|
1119
|
-
for (let i = 0, ii = attributes.length; i < ii; ++i) {
|
|
1120
|
-
const current = attributes[i];
|
|
1121
|
-
observedAttributes[i] = current.attribute;
|
|
1122
|
-
propertyLookup[current.name] = current;
|
|
1123
|
-
attributeLookup[current.attribute] = current;
|
|
1124
|
-
}
|
|
1125
|
-
this.attributes = attributes;
|
|
1126
|
-
this.observedAttributes = observedAttributes;
|
|
1127
|
-
this.propertyLookup = propertyLookup;
|
|
1128
|
-
this.attributeLookup = attributeLookup;
|
|
1129
|
-
this.shadowOptions = nameOrConfig.shadowOptions === void 0 ? defaultShadowOptions : nameOrConfig.shadowOptions === null ? void 0 : Object.assign(Object.assign({}, defaultShadowOptions), nameOrConfig.shadowOptions);
|
|
1130
|
-
this.elementOptions = nameOrConfig.elementOptions === void 0 ? defaultElementOptions : Object.assign(Object.assign({}, defaultElementOptions), nameOrConfig.elementOptions);
|
|
1131
|
-
this.styles = nameOrConfig.styles === void 0 ? void 0 : Array.isArray(nameOrConfig.styles) ? ElementStyles.create(nameOrConfig.styles) : nameOrConfig.styles instanceof ElementStyles ? nameOrConfig.styles : ElementStyles.create([nameOrConfig.styles]);
|
|
1132
|
-
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Indicates if this element has been defined in at least one registry.
|
|
1135
|
-
*/
|
|
1136
|
-
get isDefined() {
|
|
1137
|
-
return !!fastRegistry.getByType(this.type);
|
|
1138
|
-
}
|
|
1139
|
-
/**
|
|
1140
|
-
* Defines a custom element based on this definition.
|
|
1141
|
-
* @param registry - The element registry to define the element in.
|
|
1142
|
-
*/
|
|
1143
|
-
define(registry = customElements) {
|
|
1144
|
-
const type = this.type;
|
|
1145
|
-
if (fastRegistry.register(this)) {
|
|
1146
|
-
const attributes = this.attributes;
|
|
1147
|
-
const proto = type.prototype;
|
|
1148
|
-
for (let i = 0, ii = attributes.length; i < ii; ++i) {
|
|
1149
|
-
Observable.defineProperty(proto, attributes[i]);
|
|
1150
|
-
}
|
|
1151
|
-
Reflect.defineProperty(type, "observedAttributes", {
|
|
1152
|
-
value: this.observedAttributes,
|
|
1153
|
-
enumerable: true
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
if (!registry.get(this.name)) {
|
|
1157
|
-
registry.define(this.name, type, this.elementOptions);
|
|
1158
|
-
}
|
|
1159
|
-
return this;
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
/**
|
|
1163
|
-
* Gets the element definition associated with the specified type.
|
|
1164
|
-
* @param type - The custom element type to retrieve the definition for.
|
|
1165
|
-
*/
|
|
1166
|
-
FASTElementDefinition.forType = fastRegistry.getByType;
|
|
1167
|
-
|
|
1168
|
-
const shadowRoots = new WeakMap();
|
|
1169
|
-
const defaultEventOptions = {
|
|
1170
|
-
bubbles: true,
|
|
1171
|
-
composed: true,
|
|
1172
|
-
cancelable: true
|
|
1173
|
-
};
|
|
1174
|
-
function getShadowRoot(element) {
|
|
1175
|
-
return element.shadowRoot || shadowRoots.get(element) || null;
|
|
1176
|
-
}
|
|
1177
|
-
/**
|
|
1178
|
-
* Controls the lifecycle and rendering of a `FASTElement`.
|
|
1179
|
-
* @public
|
|
1180
|
-
*/
|
|
1181
|
-
class Controller extends PropertyChangeNotifier {
|
|
1182
|
-
/**
|
|
1183
|
-
* Creates a Controller to control the specified element.
|
|
1184
|
-
* @param element - The element to be controlled by this controller.
|
|
1185
|
-
* @param definition - The element definition metadata that instructs this
|
|
1186
|
-
* controller in how to handle rendering and other platform integrations.
|
|
1187
|
-
* @internal
|
|
1188
|
-
*/
|
|
1189
|
-
constructor(element, definition) {
|
|
1190
|
-
super(element);
|
|
1191
|
-
this.boundObservables = null;
|
|
1192
|
-
this.behaviors = null;
|
|
1193
|
-
this.needsInitialization = true;
|
|
1194
|
-
this._template = null;
|
|
1195
|
-
this._styles = null;
|
|
1196
|
-
this._isConnected = false;
|
|
1197
|
-
/**
|
|
1198
|
-
* This allows Observable.getNotifier(...) to return the Controller
|
|
1199
|
-
* when the notifier for the Controller itself is being requested. The
|
|
1200
|
-
* result is that the Observable system does not need to create a separate
|
|
1201
|
-
* instance of Notifier for observables on the Controller. The component and
|
|
1202
|
-
* the controller will now share the same notifier, removing one-object construct
|
|
1203
|
-
* per web component instance.
|
|
1204
|
-
*/
|
|
1205
|
-
this.$fastController = this;
|
|
1206
|
-
/**
|
|
1207
|
-
* The view associated with the custom element.
|
|
1208
|
-
* @remarks
|
|
1209
|
-
* If `null` then the element is managing its own rendering.
|
|
1210
|
-
*/
|
|
1211
|
-
this.view = null;
|
|
1212
|
-
this.element = element;
|
|
1213
|
-
this.definition = definition;
|
|
1214
|
-
const shadowOptions = definition.shadowOptions;
|
|
1215
|
-
if (shadowOptions !== void 0) {
|
|
1216
|
-
const shadowRoot = element.attachShadow(shadowOptions);
|
|
1217
|
-
if (shadowOptions.mode === "closed") {
|
|
1218
|
-
shadowRoots.set(element, shadowRoot);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
// Capture any observable values that were set by the binding engine before
|
|
1222
|
-
// the browser upgraded the element. Then delete the property since it will
|
|
1223
|
-
// shadow the getter/setter that is required to make the observable operate.
|
|
1224
|
-
// Later, in the connect callback, we'll re-apply the values.
|
|
1225
|
-
const accessors = Observable.getAccessors(element);
|
|
1226
|
-
if (accessors.length > 0) {
|
|
1227
|
-
const boundObservables = this.boundObservables = Object.create(null);
|
|
1228
|
-
for (let i = 0, ii = accessors.length; i < ii; ++i) {
|
|
1229
|
-
const propertyName = accessors[i].name;
|
|
1230
|
-
const value = element[propertyName];
|
|
1231
|
-
if (value !== void 0) {
|
|
1232
|
-
delete element[propertyName];
|
|
1233
|
-
boundObservables[propertyName] = value;
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
/**
|
|
1239
|
-
* Indicates whether or not the custom element has been
|
|
1240
|
-
* connected to the document.
|
|
1241
|
-
*/
|
|
1242
|
-
get isConnected() {
|
|
1243
|
-
Observable.track(this, "isConnected");
|
|
1244
|
-
return this._isConnected;
|
|
1245
|
-
}
|
|
1246
|
-
setIsConnected(value) {
|
|
1247
|
-
this._isConnected = value;
|
|
1248
|
-
Observable.notify(this, "isConnected");
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* Gets/sets the template used to render the component.
|
|
1252
|
-
* @remarks
|
|
1253
|
-
* This value can only be accurately read after connect but can be set at any time.
|
|
1254
|
-
*/
|
|
1255
|
-
get template() {
|
|
1256
|
-
return this._template;
|
|
1257
|
-
}
|
|
1258
|
-
set template(value) {
|
|
1259
|
-
if (this._template === value) {
|
|
1260
|
-
return;
|
|
1261
|
-
}
|
|
1262
|
-
this._template = value;
|
|
1263
|
-
if (!this.needsInitialization) {
|
|
1264
|
-
this.renderTemplate(value);
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
/**
|
|
1268
|
-
* Gets/sets the primary styles used for the component.
|
|
1269
|
-
* @remarks
|
|
1270
|
-
* This value can only be accurately read after connect but can be set at any time.
|
|
1271
|
-
*/
|
|
1272
|
-
get styles() {
|
|
1273
|
-
return this._styles;
|
|
1274
|
-
}
|
|
1275
|
-
set styles(value) {
|
|
1276
|
-
if (this._styles === value) {
|
|
1277
|
-
return;
|
|
1278
|
-
}
|
|
1279
|
-
if (this._styles !== null) {
|
|
1280
|
-
this.removeStyles(this._styles);
|
|
1281
|
-
}
|
|
1282
|
-
this._styles = value;
|
|
1283
|
-
if (!this.needsInitialization && value !== null) {
|
|
1284
|
-
this.addStyles(value);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
/**
|
|
1288
|
-
* Adds styles to this element. Providing an HTMLStyleElement will attach the element instance to the shadowRoot.
|
|
1289
|
-
* @param styles - The styles to add.
|
|
1290
|
-
*/
|
|
1291
|
-
addStyles(styles) {
|
|
1292
|
-
const target = getShadowRoot(this.element) || this.element.getRootNode();
|
|
1293
|
-
if (styles instanceof HTMLStyleElement) {
|
|
1294
|
-
target.append(styles);
|
|
1295
|
-
} else if (!styles.isAttachedTo(target)) {
|
|
1296
|
-
const sourceBehaviors = styles.behaviors;
|
|
1297
|
-
styles.addStylesTo(target);
|
|
1298
|
-
if (sourceBehaviors !== null) {
|
|
1299
|
-
this.addBehaviors(sourceBehaviors);
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
/**
|
|
1304
|
-
* Removes styles from this element. Providing an HTMLStyleElement will detach the element instance from the shadowRoot.
|
|
1305
|
-
* @param styles - the styles to remove.
|
|
1306
|
-
*/
|
|
1307
|
-
removeStyles(styles) {
|
|
1308
|
-
const target = getShadowRoot(this.element) || this.element.getRootNode();
|
|
1309
|
-
if (styles instanceof HTMLStyleElement) {
|
|
1310
|
-
target.removeChild(styles);
|
|
1311
|
-
} else if (styles.isAttachedTo(target)) {
|
|
1312
|
-
const sourceBehaviors = styles.behaviors;
|
|
1313
|
-
styles.removeStylesFrom(target);
|
|
1314
|
-
if (sourceBehaviors !== null) {
|
|
1315
|
-
this.removeBehaviors(sourceBehaviors);
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
/**
|
|
1320
|
-
* Adds behaviors to this element.
|
|
1321
|
-
* @param behaviors - The behaviors to add.
|
|
1322
|
-
*/
|
|
1323
|
-
addBehaviors(behaviors) {
|
|
1324
|
-
const targetBehaviors = this.behaviors || (this.behaviors = new Map());
|
|
1325
|
-
const length = behaviors.length;
|
|
1326
|
-
const behaviorsToBind = [];
|
|
1327
|
-
for (let i = 0; i < length; ++i) {
|
|
1328
|
-
const behavior = behaviors[i];
|
|
1329
|
-
if (targetBehaviors.has(behavior)) {
|
|
1330
|
-
targetBehaviors.set(behavior, targetBehaviors.get(behavior) + 1);
|
|
1331
|
-
} else {
|
|
1332
|
-
targetBehaviors.set(behavior, 1);
|
|
1333
|
-
behaviorsToBind.push(behavior);
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
if (this._isConnected) {
|
|
1337
|
-
const element = this.element;
|
|
1338
|
-
for (let i = 0; i < behaviorsToBind.length; ++i) {
|
|
1339
|
-
behaviorsToBind[i].bind(element, defaultExecutionContext);
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Removes behaviors from this element.
|
|
1345
|
-
* @param behaviors - The behaviors to remove.
|
|
1346
|
-
* @param force - Forces unbinding of behaviors.
|
|
1347
|
-
*/
|
|
1348
|
-
removeBehaviors(behaviors, force = false) {
|
|
1349
|
-
const targetBehaviors = this.behaviors;
|
|
1350
|
-
if (targetBehaviors === null) {
|
|
1351
|
-
return;
|
|
1352
|
-
}
|
|
1353
|
-
const length = behaviors.length;
|
|
1354
|
-
const behaviorsToUnbind = [];
|
|
1355
|
-
for (let i = 0; i < length; ++i) {
|
|
1356
|
-
const behavior = behaviors[i];
|
|
1357
|
-
if (targetBehaviors.has(behavior)) {
|
|
1358
|
-
const count = targetBehaviors.get(behavior) - 1;
|
|
1359
|
-
count === 0 || force ? targetBehaviors.delete(behavior) && behaviorsToUnbind.push(behavior) : targetBehaviors.set(behavior, count);
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
if (this._isConnected) {
|
|
1363
|
-
const element = this.element;
|
|
1364
|
-
for (let i = 0; i < behaviorsToUnbind.length; ++i) {
|
|
1365
|
-
behaviorsToUnbind[i].unbind(element);
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
/**
|
|
1370
|
-
* Runs connected lifecycle behavior on the associated element.
|
|
1371
|
-
*/
|
|
1372
|
-
onConnectedCallback() {
|
|
1373
|
-
if (this._isConnected) {
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
const element = this.element;
|
|
1377
|
-
if (this.needsInitialization) {
|
|
1378
|
-
this.finishInitialization();
|
|
1379
|
-
} else if (this.view !== null) {
|
|
1380
|
-
this.view.bind(element, defaultExecutionContext);
|
|
1381
|
-
}
|
|
1382
|
-
const behaviors = this.behaviors;
|
|
1383
|
-
if (behaviors !== null) {
|
|
1384
|
-
for (const [behavior] of behaviors) {
|
|
1385
|
-
behavior.bind(element, defaultExecutionContext);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
this.setIsConnected(true);
|
|
1389
|
-
}
|
|
1390
|
-
/**
|
|
1391
|
-
* Runs disconnected lifecycle behavior on the associated element.
|
|
1392
|
-
*/
|
|
1393
|
-
onDisconnectedCallback() {
|
|
1394
|
-
if (!this._isConnected) {
|
|
1395
|
-
return;
|
|
1396
|
-
}
|
|
1397
|
-
this.setIsConnected(false);
|
|
1398
|
-
const view = this.view;
|
|
1399
|
-
if (view !== null) {
|
|
1400
|
-
view.unbind();
|
|
1401
|
-
}
|
|
1402
|
-
const behaviors = this.behaviors;
|
|
1403
|
-
if (behaviors !== null) {
|
|
1404
|
-
const element = this.element;
|
|
1405
|
-
for (const [behavior] of behaviors) {
|
|
1406
|
-
behavior.unbind(element);
|
|
1407
|
-
}
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
/**
|
|
1411
|
-
* Runs the attribute changed callback for the associated element.
|
|
1412
|
-
* @param name - The name of the attribute that changed.
|
|
1413
|
-
* @param oldValue - The previous value of the attribute.
|
|
1414
|
-
* @param newValue - The new value of the attribute.
|
|
1415
|
-
*/
|
|
1416
|
-
onAttributeChangedCallback(name, oldValue, newValue) {
|
|
1417
|
-
const attrDef = this.definition.attributeLookup[name];
|
|
1418
|
-
if (attrDef !== void 0) {
|
|
1419
|
-
attrDef.onAttributeChangedCallback(this.element, newValue);
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
/**
|
|
1423
|
-
* Emits a custom HTML event.
|
|
1424
|
-
* @param type - The type name of the event.
|
|
1425
|
-
* @param detail - The event detail object to send with the event.
|
|
1426
|
-
* @param options - The event options. By default bubbles and composed.
|
|
1427
|
-
* @remarks
|
|
1428
|
-
* Only emits events if connected.
|
|
1429
|
-
*/
|
|
1430
|
-
emit(type, detail, options) {
|
|
1431
|
-
if (this._isConnected) {
|
|
1432
|
-
return this.element.dispatchEvent(new CustomEvent(type, Object.assign(Object.assign({
|
|
1433
|
-
detail
|
|
1434
|
-
}, defaultEventOptions), options)));
|
|
1435
|
-
}
|
|
1436
|
-
return false;
|
|
1437
|
-
}
|
|
1438
|
-
finishInitialization() {
|
|
1439
|
-
const element = this.element;
|
|
1440
|
-
const boundObservables = this.boundObservables;
|
|
1441
|
-
// If we have any observables that were bound, re-apply their values.
|
|
1442
|
-
if (boundObservables !== null) {
|
|
1443
|
-
const propertyNames = Object.keys(boundObservables);
|
|
1444
|
-
for (let i = 0, ii = propertyNames.length; i < ii; ++i) {
|
|
1445
|
-
const propertyName = propertyNames[i];
|
|
1446
|
-
element[propertyName] = boundObservables[propertyName];
|
|
1447
|
-
}
|
|
1448
|
-
this.boundObservables = null;
|
|
1449
|
-
}
|
|
1450
|
-
const definition = this.definition;
|
|
1451
|
-
// 1. Template overrides take top precedence.
|
|
1452
|
-
if (this._template === null) {
|
|
1453
|
-
if (this.element.resolveTemplate) {
|
|
1454
|
-
// 2. Allow for element instance overrides next.
|
|
1455
|
-
this._template = this.element.resolveTemplate();
|
|
1456
|
-
} else if (definition.template) {
|
|
1457
|
-
// 3. Default to the static definition.
|
|
1458
|
-
this._template = definition.template || null;
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
// If we have a template after the above process, render it.
|
|
1462
|
-
// If there's no template, then the element author has opted into
|
|
1463
|
-
// custom rendering and they will managed the shadow root's content themselves.
|
|
1464
|
-
if (this._template !== null) {
|
|
1465
|
-
this.renderTemplate(this._template);
|
|
1466
|
-
}
|
|
1467
|
-
// 1. Styles overrides take top precedence.
|
|
1468
|
-
if (this._styles === null) {
|
|
1469
|
-
if (this.element.resolveStyles) {
|
|
1470
|
-
// 2. Allow for element instance overrides next.
|
|
1471
|
-
this._styles = this.element.resolveStyles();
|
|
1472
|
-
} else if (definition.styles) {
|
|
1473
|
-
// 3. Default to the static definition.
|
|
1474
|
-
this._styles = definition.styles || null;
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
// If we have styles after the above process, add them.
|
|
1478
|
-
if (this._styles !== null) {
|
|
1479
|
-
this.addStyles(this._styles);
|
|
1480
|
-
}
|
|
1481
|
-
this.needsInitialization = false;
|
|
1482
|
-
}
|
|
1483
|
-
renderTemplate(template) {
|
|
1484
|
-
const element = this.element;
|
|
1485
|
-
// When getting the host to render to, we start by looking
|
|
1486
|
-
// up the shadow root. If there isn't one, then that means
|
|
1487
|
-
// we're doing a Light DOM render to the element's direct children.
|
|
1488
|
-
const host = getShadowRoot(element) || element;
|
|
1489
|
-
if (this.view !== null) {
|
|
1490
|
-
// If there's already a view, we need to unbind and remove through dispose.
|
|
1491
|
-
this.view.dispose();
|
|
1492
|
-
this.view = null;
|
|
1493
|
-
} else if (!this.needsInitialization) {
|
|
1494
|
-
// If there was previous custom rendering, we need to clear out the host.
|
|
1495
|
-
DOM.removeChildNodes(host);
|
|
1496
|
-
}
|
|
1497
|
-
if (template) {
|
|
1498
|
-
// If a new template was provided, render it.
|
|
1499
|
-
this.view = template.render(element, host, element);
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
/**
|
|
1503
|
-
* Locates or creates a controller for the specified element.
|
|
1504
|
-
* @param element - The element to return the controller for.
|
|
1505
|
-
* @remarks
|
|
1506
|
-
* The specified element must have a {@link FASTElementDefinition}
|
|
1507
|
-
* registered either through the use of the {@link customElement}
|
|
1508
|
-
* decorator or a call to `FASTElement.define`.
|
|
1509
|
-
*/
|
|
1510
|
-
static forCustomElement(element) {
|
|
1511
|
-
const controller = element.$fastController;
|
|
1512
|
-
if (controller !== void 0) {
|
|
1513
|
-
return controller;
|
|
1514
|
-
}
|
|
1515
|
-
const definition = FASTElementDefinition.forType(element.constructor);
|
|
1516
|
-
if (definition === void 0) {
|
|
1517
|
-
throw new Error("Missing FASTElement definition.");
|
|
1518
|
-
}
|
|
1519
|
-
return element.$fastController = new Controller(element, definition);
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
1524
|
-
function createFASTElement(BaseType) {
|
|
1525
|
-
return class extends BaseType {
|
|
1526
|
-
constructor() {
|
|
1527
|
-
/* eslint-disable-next-line */
|
|
1528
|
-
super();
|
|
1529
|
-
Controller.forCustomElement(this);
|
|
1530
|
-
}
|
|
1531
|
-
$emit(type, detail, options) {
|
|
1532
|
-
return this.$fastController.emit(type, detail, options);
|
|
1533
|
-
}
|
|
1534
|
-
connectedCallback() {
|
|
1535
|
-
this.$fastController.onConnectedCallback();
|
|
1536
|
-
}
|
|
1537
|
-
disconnectedCallback() {
|
|
1538
|
-
this.$fastController.onDisconnectedCallback();
|
|
1539
|
-
}
|
|
1540
|
-
attributeChangedCallback(name, oldValue, newValue) {
|
|
1541
|
-
this.$fastController.onAttributeChangedCallback(name, oldValue, newValue);
|
|
1542
|
-
}
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
/**
|
|
1546
|
-
* A minimal base class for FASTElements that also provides
|
|
1547
|
-
* static helpers for working with FASTElements.
|
|
1548
|
-
* @public
|
|
1549
|
-
*/
|
|
1550
|
-
const FASTElement = Object.assign(createFASTElement(HTMLElement), {
|
|
1551
|
-
/**
|
|
1552
|
-
* Creates a new FASTElement base class inherited from the
|
|
1553
|
-
* provided base type.
|
|
1554
|
-
* @param BaseType - The base element type to inherit from.
|
|
1555
|
-
*/
|
|
1556
|
-
from(BaseType) {
|
|
1557
|
-
return createFASTElement(BaseType);
|
|
1558
|
-
},
|
|
1559
|
-
/**
|
|
1560
|
-
* Defines a platform custom element based on the provided type and definition.
|
|
1561
|
-
* @param type - The custom element type to define.
|
|
1562
|
-
* @param nameOrDef - The name of the element to define or a definition object
|
|
1563
|
-
* that describes the element to define.
|
|
1564
|
-
*/
|
|
1565
|
-
define(type, nameOrDef) {
|
|
1566
|
-
return new FASTElementDefinition(type, nameOrDef).define().type;
|
|
1567
|
-
}
|
|
1568
|
-
});
|
|
1569
|
-
|
|
1570
|
-
/**
|
|
1571
|
-
* Big thanks to https://github.com/fkleuver and the https://github.com/aurelia/aurelia project
|
|
1572
|
-
* for the bulk of this code and many of the associated tests.
|
|
1573
|
-
*/
|
|
1574
|
-
// Tiny polyfill for TypeScript's Reflect metadata API.
|
|
1575
|
-
const metadataByTarget = new Map();
|
|
1576
|
-
if (!("metadata" in Reflect)) {
|
|
1577
|
-
Reflect.metadata = function (key, value) {
|
|
1578
|
-
return function (target) {
|
|
1579
|
-
Reflect.defineMetadata(key, value, target);
|
|
1580
|
-
};
|
|
1581
|
-
};
|
|
1582
|
-
Reflect.defineMetadata = function (key, value, target) {
|
|
1583
|
-
let metadata = metadataByTarget.get(target);
|
|
1584
|
-
if (metadata === void 0) {
|
|
1585
|
-
metadataByTarget.set(target, metadata = new Map());
|
|
1586
|
-
}
|
|
1587
|
-
metadata.set(key, value);
|
|
1588
|
-
};
|
|
1589
|
-
Reflect.getOwnMetadata = function (key, target) {
|
|
1590
|
-
const metadata = metadataByTarget.get(target);
|
|
1591
|
-
if (metadata !== void 0) {
|
|
1592
|
-
return metadata.get(key);
|
|
1593
|
-
}
|
|
1594
|
-
return void 0;
|
|
1595
|
-
};
|
|
1596
|
-
}
|
|
1597
|
-
/**
|
|
1598
|
-
* A utility class used that constructs and registers resolvers for a dependency
|
|
1599
|
-
* injection container. Supports a standard set of object lifetimes.
|
|
1600
|
-
* @public
|
|
1601
|
-
*/
|
|
1602
|
-
class ResolverBuilder {
|
|
1603
|
-
/**
|
|
1604
|
-
*
|
|
1605
|
-
* @param container - The container to create resolvers for.
|
|
1606
|
-
* @param key - The key to register resolvers under.
|
|
1607
|
-
*/
|
|
1608
|
-
constructor(container, key) {
|
|
1609
|
-
this.container = container;
|
|
1610
|
-
this.key = key;
|
|
1611
|
-
}
|
|
1612
|
-
/**
|
|
1613
|
-
* Creates a resolver for an existing object instance.
|
|
1614
|
-
* @param value - The instance to resolve.
|
|
1615
|
-
* @returns The resolver.
|
|
1616
|
-
*/
|
|
1617
|
-
instance(value) {
|
|
1618
|
-
return this.registerResolver(0 /* instance */, value);
|
|
1619
|
-
}
|
|
1620
|
-
/**
|
|
1621
|
-
* Creates a resolver that enforces a singleton lifetime.
|
|
1622
|
-
* @param value - The type to create and cache the singleton for.
|
|
1623
|
-
* @returns The resolver.
|
|
1624
|
-
*/
|
|
1625
|
-
singleton(value) {
|
|
1626
|
-
return this.registerResolver(1 /* singleton */, value);
|
|
1627
|
-
}
|
|
1628
|
-
/**
|
|
1629
|
-
* Creates a resolver that creates a new instance for every dependency request.
|
|
1630
|
-
* @param value - The type to create instances of.
|
|
1631
|
-
* @returns - The resolver.
|
|
1632
|
-
*/
|
|
1633
|
-
transient(value) {
|
|
1634
|
-
return this.registerResolver(2 /* transient */, value);
|
|
1635
|
-
}
|
|
1636
|
-
/**
|
|
1637
|
-
* Creates a resolver that invokes a callback function for every dependency resolution
|
|
1638
|
-
* request, allowing custom logic to return the dependency.
|
|
1639
|
-
* @param value - The callback to call during resolution.
|
|
1640
|
-
* @returns The resolver.
|
|
1641
|
-
*/
|
|
1642
|
-
callback(value) {
|
|
1643
|
-
return this.registerResolver(3 /* callback */, value);
|
|
1644
|
-
}
|
|
1645
|
-
/**
|
|
1646
|
-
* Creates a resolver that invokes a callback function the first time that a dependency
|
|
1647
|
-
* resolution is requested. The returned value is then cached and provided for all
|
|
1648
|
-
* subsequent requests.
|
|
1649
|
-
* @param value - The callback to call during the first resolution.
|
|
1650
|
-
* @returns The resolver.
|
|
1651
|
-
*/
|
|
1652
|
-
cachedCallback(value) {
|
|
1653
|
-
return this.registerResolver(3 /* callback */, cacheCallbackResult(value));
|
|
1654
|
-
}
|
|
1655
|
-
/**
|
|
1656
|
-
* Aliases the current key to a different key.
|
|
1657
|
-
* @param destinationKey - The key to point the alias to.
|
|
1658
|
-
* @returns The resolver.
|
|
1659
|
-
*/
|
|
1660
|
-
aliasTo(destinationKey) {
|
|
1661
|
-
return this.registerResolver(5 /* alias */, destinationKey);
|
|
1662
|
-
}
|
|
1663
|
-
registerResolver(strategy, state) {
|
|
1664
|
-
const {
|
|
1665
|
-
container,
|
|
1666
|
-
key
|
|
1667
|
-
} = this;
|
|
1668
|
-
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
|
1669
|
-
this.container = this.key = void 0;
|
|
1670
|
-
return container.registerResolver(key, new ResolverImpl(key, strategy, state));
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
function cloneArrayWithPossibleProps(source) {
|
|
1674
|
-
const clone = source.slice();
|
|
1675
|
-
const keys = Object.keys(source);
|
|
1676
|
-
const len = keys.length;
|
|
1677
|
-
let key;
|
|
1678
|
-
for (let i = 0; i < len; ++i) {
|
|
1679
|
-
key = keys[i];
|
|
1680
|
-
if (!isArrayIndex(key)) {
|
|
1681
|
-
clone[key] = source[key];
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
return clone;
|
|
1685
|
-
}
|
|
1686
|
-
/**
|
|
1687
|
-
* A set of default resolvers useful in configuring a container.
|
|
1688
|
-
* @public
|
|
1689
|
-
*/
|
|
1690
|
-
const DefaultResolver = Object.freeze({
|
|
1691
|
-
/**
|
|
1692
|
-
* Disables auto-registration and throws for all un-registered dependencies.
|
|
1693
|
-
* @param key - The key to create the resolver for.
|
|
1694
|
-
*/
|
|
1695
|
-
none(key) {
|
|
1696
|
-
throw Error(`${key.toString()} not registered, did you forget to add @singleton()?`);
|
|
1697
|
-
},
|
|
1698
|
-
/**
|
|
1699
|
-
* Provides default singleton resolution behavior during auto-registration.
|
|
1700
|
-
* @param key - The key to create the resolver for.
|
|
1701
|
-
* @returns The resolver.
|
|
1702
|
-
*/
|
|
1703
|
-
singleton(key) {
|
|
1704
|
-
return new ResolverImpl(key, 1 /* singleton */, key);
|
|
1705
|
-
},
|
|
1706
|
-
/**
|
|
1707
|
-
* Provides default transient resolution behavior during auto-registration.
|
|
1708
|
-
* @param key - The key to create the resolver for.
|
|
1709
|
-
* @returns The resolver.
|
|
1710
|
-
*/
|
|
1711
|
-
transient(key) {
|
|
1712
|
-
return new ResolverImpl(key, 2 /* transient */, key);
|
|
1713
|
-
}
|
|
1714
|
-
});
|
|
1715
|
-
/**
|
|
1716
|
-
* Configuration for a dependency injection container.
|
|
1717
|
-
* @public
|
|
1718
|
-
*/
|
|
1719
|
-
const ContainerConfiguration = Object.freeze({
|
|
1720
|
-
/**
|
|
1721
|
-
* The default configuration used when creating a DOM-disconnected container.
|
|
1722
|
-
* @remarks
|
|
1723
|
-
* The default creates a root container, with no parent container. It does not handle
|
|
1724
|
-
* owner requests and it uses singleton resolution behavior for auto-registration.
|
|
1725
|
-
*/
|
|
1726
|
-
default: Object.freeze({
|
|
1727
|
-
parentLocator: () => null,
|
|
1728
|
-
responsibleForOwnerRequests: false,
|
|
1729
|
-
defaultResolver: DefaultResolver.singleton
|
|
1730
|
-
})
|
|
1731
|
-
});
|
|
1732
|
-
const dependencyLookup = new Map();
|
|
1733
|
-
function getParamTypes(key) {
|
|
1734
|
-
return Type => {
|
|
1735
|
-
return Reflect.getOwnMetadata(key, Type);
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
let rootDOMContainer = null;
|
|
1739
|
-
/**
|
|
1740
|
-
* The gateway to dependency injection APIs.
|
|
1741
|
-
* @public
|
|
1742
|
-
*/
|
|
1743
|
-
const DI = Object.freeze({
|
|
1744
|
-
/**
|
|
1745
|
-
* Creates a new dependency injection container.
|
|
1746
|
-
* @param config - The configuration for the container.
|
|
1747
|
-
* @returns A newly created dependency injection container.
|
|
1748
|
-
*/
|
|
1749
|
-
createContainer(config) {
|
|
1750
|
-
return new ContainerImpl(null, Object.assign({}, ContainerConfiguration.default, config));
|
|
1751
|
-
},
|
|
1752
|
-
/**
|
|
1753
|
-
* Finds the dependency injection container responsible for providing dependencies
|
|
1754
|
-
* to the specified node.
|
|
1755
|
-
* @param node - The node to find the responsible container for.
|
|
1756
|
-
* @returns The container responsible for providing dependencies to the node.
|
|
1757
|
-
* @remarks
|
|
1758
|
-
* This will be the same as the parent container if the specified node
|
|
1759
|
-
* does not itself host a container configured with responsibleForOwnerRequests.
|
|
1760
|
-
*/
|
|
1761
|
-
findResponsibleContainer(node) {
|
|
1762
|
-
const owned = node.$$container$$;
|
|
1763
|
-
if (owned && owned.responsibleForOwnerRequests) {
|
|
1764
|
-
return owned;
|
|
1765
|
-
}
|
|
1766
|
-
return DI.findParentContainer(node);
|
|
1767
|
-
},
|
|
1768
|
-
/**
|
|
1769
|
-
* Find the dependency injection container up the DOM tree from this node.
|
|
1770
|
-
* @param node - The node to find the parent container for.
|
|
1771
|
-
* @returns The parent container of this node.
|
|
1772
|
-
* @remarks
|
|
1773
|
-
* This will be the same as the responsible container if the specified node
|
|
1774
|
-
* does not itself host a container configured with responsibleForOwnerRequests.
|
|
1775
|
-
*/
|
|
1776
|
-
findParentContainer(node) {
|
|
1777
|
-
const event = new CustomEvent(DILocateParentEventType, {
|
|
1778
|
-
bubbles: true,
|
|
1779
|
-
composed: true,
|
|
1780
|
-
cancelable: true,
|
|
1781
|
-
detail: {
|
|
1782
|
-
container: void 0
|
|
1783
|
-
}
|
|
1784
|
-
});
|
|
1785
|
-
node.dispatchEvent(event);
|
|
1786
|
-
return event.detail.container || DI.getOrCreateDOMContainer();
|
|
1787
|
-
},
|
|
1788
|
-
/**
|
|
1789
|
-
* Returns a dependency injection container if one is explicitly owned by the specified
|
|
1790
|
-
* node. If one is not owned, then a new container is created and assigned to the node.
|
|
1791
|
-
* @param node - The node to find or create the container for.
|
|
1792
|
-
* @param config - The configuration for the container if one needs to be created.
|
|
1793
|
-
* @returns The located or created container.
|
|
1794
|
-
* @remarks
|
|
1795
|
-
* This API does not search for a responsible or parent container. It looks only for a container
|
|
1796
|
-
* directly defined on the specified node and creates one at that location if one does not
|
|
1797
|
-
* already exist.
|
|
1798
|
-
*/
|
|
1799
|
-
getOrCreateDOMContainer(node, config) {
|
|
1800
|
-
if (!node) {
|
|
1801
|
-
return rootDOMContainer || (rootDOMContainer = new ContainerImpl(null, Object.assign({}, ContainerConfiguration.default, config, {
|
|
1802
|
-
parentLocator: () => null
|
|
1803
|
-
})));
|
|
1804
|
-
}
|
|
1805
|
-
return node.$$container$$ || new ContainerImpl(node, Object.assign({}, ContainerConfiguration.default, config, {
|
|
1806
|
-
parentLocator: DI.findParentContainer
|
|
1807
|
-
}));
|
|
1808
|
-
},
|
|
1809
|
-
/**
|
|
1810
|
-
* Gets the "design:paramtypes" metadata for the specified type.
|
|
1811
|
-
* @param Type - The type to get the metadata for.
|
|
1812
|
-
* @returns The metadata array or undefined if no metadata is found.
|
|
1813
|
-
*/
|
|
1814
|
-
getDesignParamtypes: getParamTypes("design:paramtypes"),
|
|
1815
|
-
/**
|
|
1816
|
-
* Gets the "di:paramtypes" metadata for the specified type.
|
|
1817
|
-
* @param Type - The type to get the metadata for.
|
|
1818
|
-
* @returns The metadata array or undefined if no metadata is found.
|
|
1819
|
-
*/
|
|
1820
|
-
getAnnotationParamtypes: getParamTypes("di:paramtypes"),
|
|
1821
|
-
/**
|
|
1822
|
-
*
|
|
1823
|
-
* @param Type - Gets the "di:paramtypes" metadata for the specified type. If none is found,
|
|
1824
|
-
* an empty metadata array is created and added.
|
|
1825
|
-
* @returns The metadata array.
|
|
1826
|
-
*/
|
|
1827
|
-
getOrCreateAnnotationParamTypes(Type) {
|
|
1828
|
-
let annotationParamtypes = this.getAnnotationParamtypes(Type);
|
|
1829
|
-
if (annotationParamtypes === void 0) {
|
|
1830
|
-
Reflect.defineMetadata("di:paramtypes", annotationParamtypes = [], Type);
|
|
1831
|
-
}
|
|
1832
|
-
return annotationParamtypes;
|
|
1833
|
-
},
|
|
1834
|
-
/**
|
|
1835
|
-
* Gets the dependency keys representing what is needed to instantiate the specified type.
|
|
1836
|
-
* @param Type - The type to get the dependencies for.
|
|
1837
|
-
* @returns An array of dependency keys.
|
|
1838
|
-
*/
|
|
1839
|
-
getDependencies(Type) {
|
|
1840
|
-
// Note: Every detail of this getDependencies method is pretty deliberate at the moment, and probably not yet 100% tested from every possible angle,
|
|
1841
|
-
// so be careful with making changes here as it can have a huge impact on complex end user apps.
|
|
1842
|
-
// Preferably, only make changes to the dependency resolution process via a RFC.
|
|
1843
|
-
let dependencies = dependencyLookup.get(Type);
|
|
1844
|
-
if (dependencies === void 0) {
|
|
1845
|
-
// Type.length is the number of constructor parameters. If this is 0, it could mean the class has an empty constructor
|
|
1846
|
-
// but it could also mean the class has no constructor at all (in which case it inherits the constructor from the prototype).
|
|
1847
|
-
// Non-zero constructor length + no paramtypes means emitDecoratorMetadata is off, or the class has no decorator.
|
|
1848
|
-
// We're not doing anything with the above right now, but it's good to keep in mind for any future issues.
|
|
1849
|
-
const inject = Type.inject;
|
|
1850
|
-
if (inject === void 0) {
|
|
1851
|
-
// design:paramtypes is set by tsc when emitDecoratorMetadata is enabled.
|
|
1852
|
-
const designParamtypes = DI.getDesignParamtypes(Type);
|
|
1853
|
-
// di:paramtypes is set by the parameter decorator from DI.createInterface or by @inject
|
|
1854
|
-
const annotationParamtypes = DI.getAnnotationParamtypes(Type);
|
|
1855
|
-
if (designParamtypes === void 0) {
|
|
1856
|
-
if (annotationParamtypes === void 0) {
|
|
1857
|
-
// Only go up the prototype if neither static inject nor any of the paramtypes is defined, as
|
|
1858
|
-
// there is no sound way to merge a type's deps with its prototype's deps
|
|
1859
|
-
const Proto = Object.getPrototypeOf(Type);
|
|
1860
|
-
if (typeof Proto === "function" && Proto !== Function.prototype) {
|
|
1861
|
-
dependencies = cloneArrayWithPossibleProps(DI.getDependencies(Proto));
|
|
1862
|
-
} else {
|
|
1863
|
-
dependencies = [];
|
|
1864
|
-
}
|
|
1865
|
-
} else {
|
|
1866
|
-
// No design:paramtypes so just use the di:paramtypes
|
|
1867
|
-
dependencies = cloneArrayWithPossibleProps(annotationParamtypes);
|
|
1868
|
-
}
|
|
1869
|
-
} else if (annotationParamtypes === void 0) {
|
|
1870
|
-
// No di:paramtypes so just use the design:paramtypes
|
|
1871
|
-
dependencies = cloneArrayWithPossibleProps(designParamtypes);
|
|
1872
|
-
} else {
|
|
1873
|
-
// We've got both, so merge them (in case of conflict on same index, di:paramtypes take precedence)
|
|
1874
|
-
dependencies = cloneArrayWithPossibleProps(designParamtypes);
|
|
1875
|
-
let len = annotationParamtypes.length;
|
|
1876
|
-
let auAnnotationParamtype;
|
|
1877
|
-
for (let i = 0; i < len; ++i) {
|
|
1878
|
-
auAnnotationParamtype = annotationParamtypes[i];
|
|
1879
|
-
if (auAnnotationParamtype !== void 0) {
|
|
1880
|
-
dependencies[i] = auAnnotationParamtype;
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
const keys = Object.keys(annotationParamtypes);
|
|
1884
|
-
len = keys.length;
|
|
1885
|
-
let key;
|
|
1886
|
-
for (let i = 0; i < len; ++i) {
|
|
1887
|
-
key = keys[i];
|
|
1888
|
-
if (!isArrayIndex(key)) {
|
|
1889
|
-
dependencies[key] = annotationParamtypes[key];
|
|
1890
|
-
}
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
} else {
|
|
1894
|
-
// Ignore paramtypes if we have static inject
|
|
1895
|
-
dependencies = cloneArrayWithPossibleProps(inject);
|
|
1896
|
-
}
|
|
1897
|
-
dependencyLookup.set(Type, dependencies);
|
|
1898
|
-
}
|
|
1899
|
-
return dependencies;
|
|
1900
|
-
},
|
|
1901
|
-
/**
|
|
1902
|
-
* Defines a property on a web component class. The value of this property will
|
|
1903
|
-
* be resolved from the dependency injection container responsible for the element
|
|
1904
|
-
* instance, based on where it is connected in the DOM.
|
|
1905
|
-
* @param target - The target to define the property on.
|
|
1906
|
-
* @param propertyName - The name of the property to define.
|
|
1907
|
-
* @param key - The dependency injection key.
|
|
1908
|
-
* @param respectConnection - Indicates whether or not to update the property value if the
|
|
1909
|
-
* hosting component is disconnected and then re-connected at a different location in the DOM.
|
|
1910
|
-
* @remarks
|
|
1911
|
-
* The respectConnection option is only applicable to elements that descend from FASTElement.
|
|
1912
|
-
*/
|
|
1913
|
-
defineProperty(target, propertyName, key, respectConnection = false) {
|
|
1914
|
-
const diPropertyKey = `$di_${propertyName}`;
|
|
1915
|
-
Reflect.defineProperty(target, propertyName, {
|
|
1916
|
-
get: function () {
|
|
1917
|
-
let value = this[diPropertyKey];
|
|
1918
|
-
if (value === void 0) {
|
|
1919
|
-
const container = this instanceof HTMLElement ? DI.findResponsibleContainer(this) : DI.getOrCreateDOMContainer();
|
|
1920
|
-
value = container.get(key);
|
|
1921
|
-
this[diPropertyKey] = value;
|
|
1922
|
-
if (respectConnection && this instanceof FASTElement) {
|
|
1923
|
-
const notifier = this.$fastController;
|
|
1924
|
-
const handleChange = () => {
|
|
1925
|
-
const newContainer = DI.findResponsibleContainer(this);
|
|
1926
|
-
const newValue = newContainer.get(key);
|
|
1927
|
-
const oldValue = this[diPropertyKey];
|
|
1928
|
-
if (newValue !== oldValue) {
|
|
1929
|
-
this[diPropertyKey] = value;
|
|
1930
|
-
notifier.notify(propertyName);
|
|
1931
|
-
}
|
|
1932
|
-
};
|
|
1933
|
-
notifier.subscribe({
|
|
1934
|
-
handleChange
|
|
1935
|
-
}, "isConnected");
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
return value;
|
|
1939
|
-
}
|
|
1940
|
-
});
|
|
1941
|
-
},
|
|
1942
|
-
/**
|
|
1943
|
-
* Creates a dependency injection key.
|
|
1944
|
-
* @param nameConfigOrCallback - A friendly name for the key or a lambda that configures a
|
|
1945
|
-
* default resolution for the dependency.
|
|
1946
|
-
* @param configuror - If a friendly name was provided for the first parameter, then an optional
|
|
1947
|
-
* lambda that configures a default resolution for the dependency can be provided second.
|
|
1948
|
-
* @returns The created key.
|
|
1949
|
-
* @remarks
|
|
1950
|
-
* The created key can be used as a property decorator or constructor parameter decorator,
|
|
1951
|
-
* in addition to its standard use in an inject array or through direct container APIs.
|
|
1952
|
-
*/
|
|
1953
|
-
createInterface(nameConfigOrCallback, configuror) {
|
|
1954
|
-
const configure = typeof nameConfigOrCallback === "function" ? nameConfigOrCallback : configuror;
|
|
1955
|
-
const friendlyName = typeof nameConfigOrCallback === "string" ? nameConfigOrCallback : nameConfigOrCallback && "friendlyName" in nameConfigOrCallback ? nameConfigOrCallback.friendlyName || defaultFriendlyName : defaultFriendlyName;
|
|
1956
|
-
const respectConnection = typeof nameConfigOrCallback === "string" ? false : nameConfigOrCallback && "respectConnection" in nameConfigOrCallback ? nameConfigOrCallback.respectConnection || false : false;
|
|
1957
|
-
const Interface = function (target, property, index) {
|
|
1958
|
-
if (target == null || new.target !== undefined) {
|
|
1959
|
-
throw new Error(`No registration for interface: '${Interface.friendlyName}'`);
|
|
1960
|
-
}
|
|
1961
|
-
if (property) {
|
|
1962
|
-
DI.defineProperty(target, property, Interface, respectConnection);
|
|
1963
|
-
} else {
|
|
1964
|
-
const annotationParamtypes = DI.getOrCreateAnnotationParamTypes(target);
|
|
1965
|
-
annotationParamtypes[index] = Interface;
|
|
1966
|
-
}
|
|
1967
|
-
};
|
|
1968
|
-
Interface.$isInterface = true;
|
|
1969
|
-
Interface.friendlyName = friendlyName == null ? "(anonymous)" : friendlyName;
|
|
1970
|
-
if (configure != null) {
|
|
1971
|
-
Interface.register = function (container, key) {
|
|
1972
|
-
return configure(new ResolverBuilder(container, key !== null && key !== void 0 ? key : Interface));
|
|
1973
|
-
};
|
|
1974
|
-
}
|
|
1975
|
-
Interface.toString = function toString() {
|
|
1976
|
-
return `InterfaceSymbol<${Interface.friendlyName}>`;
|
|
1977
|
-
};
|
|
1978
|
-
return Interface;
|
|
1979
|
-
},
|
|
1980
|
-
/**
|
|
1981
|
-
* A decorator that specifies what to inject into its target.
|
|
1982
|
-
* @param dependencies - The dependencies to inject.
|
|
1983
|
-
* @returns The decorator to be applied to the target class.
|
|
1984
|
-
* @remarks
|
|
1985
|
-
* The decorator can be used to decorate a class, listing all of the classes dependencies.
|
|
1986
|
-
* Or it can be used to decorate a constructor paramter, indicating what to inject for that
|
|
1987
|
-
* parameter.
|
|
1988
|
-
* Or it can be used for a web component property, indicating what that property should resolve to.
|
|
1989
|
-
*/
|
|
1990
|
-
inject(...dependencies) {
|
|
1991
|
-
return function (target, key, descriptor) {
|
|
1992
|
-
if (typeof descriptor === "number") {
|
|
1993
|
-
// It's a parameter decorator.
|
|
1994
|
-
const annotationParamtypes = DI.getOrCreateAnnotationParamTypes(target);
|
|
1995
|
-
const dep = dependencies[0];
|
|
1996
|
-
if (dep !== void 0) {
|
|
1997
|
-
annotationParamtypes[descriptor] = dep;
|
|
1998
|
-
}
|
|
1999
|
-
} else if (key) {
|
|
2000
|
-
DI.defineProperty(target, key, dependencies[0]);
|
|
2001
|
-
} else {
|
|
2002
|
-
const annotationParamtypes = descriptor ? DI.getOrCreateAnnotationParamTypes(descriptor.value) : DI.getOrCreateAnnotationParamTypes(target);
|
|
2003
|
-
let dep;
|
|
2004
|
-
for (let i = 0; i < dependencies.length; ++i) {
|
|
2005
|
-
dep = dependencies[i];
|
|
2006
|
-
if (dep !== void 0) {
|
|
2007
|
-
annotationParamtypes[i] = dep;
|
|
2008
|
-
}
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
};
|
|
2012
|
-
},
|
|
2013
|
-
/**
|
|
2014
|
-
* Registers the `target` class as a transient dependency; each time the dependency is resolved
|
|
2015
|
-
* a new instance will be created.
|
|
2016
|
-
*
|
|
2017
|
-
* @param target - The class / constructor function to register as transient.
|
|
2018
|
-
* @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver.
|
|
2019
|
-
*
|
|
2020
|
-
* @example
|
|
2021
|
-
* On an existing class
|
|
2022
|
-
* ```ts
|
|
2023
|
-
* class Foo { }
|
|
2024
|
-
* DI.transient(Foo);
|
|
2025
|
-
* ```
|
|
2026
|
-
*
|
|
2027
|
-
* @example
|
|
2028
|
-
* Inline declaration
|
|
2029
|
-
*
|
|
2030
|
-
* ```ts
|
|
2031
|
-
* const Foo = DI.transient(class { });
|
|
2032
|
-
* // Foo is now strongly typed with register
|
|
2033
|
-
* Foo.register(container);
|
|
2034
|
-
* ```
|
|
2035
|
-
*
|
|
2036
|
-
* @public
|
|
2037
|
-
*/
|
|
2038
|
-
transient(target) {
|
|
2039
|
-
target.register = function register(container) {
|
|
2040
|
-
const registration = Registration.transient(target, target);
|
|
2041
|
-
return registration.register(container);
|
|
2042
|
-
};
|
|
2043
|
-
target.registerInRequestor = false;
|
|
2044
|
-
return target;
|
|
2045
|
-
},
|
|
2046
|
-
/**
|
|
2047
|
-
* Registers the `target` class as a singleton dependency; the class will only be created once. Each
|
|
2048
|
-
* consecutive time the dependency is resolved, the same instance will be returned.
|
|
2049
|
-
*
|
|
2050
|
-
* @param target - The class / constructor function to register as a singleton.
|
|
2051
|
-
* @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver.
|
|
2052
|
-
* @example
|
|
2053
|
-
* On an existing class
|
|
2054
|
-
* ```ts
|
|
2055
|
-
* class Foo { }
|
|
2056
|
-
* DI.singleton(Foo);
|
|
2057
|
-
* ```
|
|
2058
|
-
*
|
|
2059
|
-
* @example
|
|
2060
|
-
* Inline declaration
|
|
2061
|
-
* ```ts
|
|
2062
|
-
* const Foo = DI.singleton(class { });
|
|
2063
|
-
* // Foo is now strongly typed with register
|
|
2064
|
-
* Foo.register(container);
|
|
2065
|
-
* ```
|
|
2066
|
-
*
|
|
2067
|
-
* @public
|
|
2068
|
-
*/
|
|
2069
|
-
singleton(target, options = defaultSingletonOptions) {
|
|
2070
|
-
target.register = function register(container) {
|
|
2071
|
-
const registration = Registration.singleton(target, target);
|
|
2072
|
-
return registration.register(container);
|
|
2073
|
-
};
|
|
2074
|
-
target.registerInRequestor = options.scoped;
|
|
2075
|
-
return target;
|
|
2076
|
-
}
|
|
2077
|
-
});
|
|
2078
|
-
/**
|
|
2079
|
-
* The interface key that resolves the dependency injection container itself.
|
|
2080
|
-
* @public
|
|
2081
|
-
*/
|
|
2082
|
-
const Container = DI.createInterface("Container");
|
|
2083
|
-
/**
|
|
2084
|
-
* A decorator that specifies what to inject into its target.
|
|
2085
|
-
* @param dependencies - The dependencies to inject.
|
|
2086
|
-
* @returns The decorator to be applied to the target class.
|
|
2087
|
-
* @remarks
|
|
2088
|
-
* The decorator can be used to decorate a class, listing all of the classes dependencies.
|
|
2089
|
-
* Or it can be used to decorate a constructor paramter, indicating what to inject for that
|
|
2090
|
-
* parameter.
|
|
2091
|
-
* Or it can be used for a web component property, indicating what that property should resolve to.
|
|
2092
|
-
*
|
|
2093
|
-
* @public
|
|
2094
|
-
*/
|
|
2095
|
-
DI.inject;
|
|
2096
|
-
const defaultSingletonOptions = {
|
|
2097
|
-
scoped: false
|
|
2098
|
-
};
|
|
2099
|
-
/** @internal */
|
|
2100
|
-
class ResolverImpl {
|
|
2101
|
-
constructor(key, strategy, state) {
|
|
2102
|
-
this.key = key;
|
|
2103
|
-
this.strategy = strategy;
|
|
2104
|
-
this.state = state;
|
|
2105
|
-
this.resolving = false;
|
|
2106
|
-
}
|
|
2107
|
-
get $isResolver() {
|
|
2108
|
-
return true;
|
|
2109
|
-
}
|
|
2110
|
-
register(container) {
|
|
2111
|
-
return container.registerResolver(this.key, this);
|
|
2112
|
-
}
|
|
2113
|
-
resolve(handler, requestor) {
|
|
2114
|
-
switch (this.strategy) {
|
|
2115
|
-
case 0 /* instance */:
|
|
2116
|
-
return this.state;
|
|
2117
|
-
case 1 /* singleton */:
|
|
2118
|
-
{
|
|
2119
|
-
if (this.resolving) {
|
|
2120
|
-
throw new Error(`Cyclic dependency found: ${this.state.name}`);
|
|
2121
|
-
}
|
|
2122
|
-
this.resolving = true;
|
|
2123
|
-
this.state = handler.getFactory(this.state).construct(requestor);
|
|
2124
|
-
this.strategy = 0 /* instance */;
|
|
2125
|
-
this.resolving = false;
|
|
2126
|
-
return this.state;
|
|
2127
|
-
}
|
|
2128
|
-
case 2 /* transient */:
|
|
2129
|
-
{
|
|
2130
|
-
// Always create transients from the requesting container
|
|
2131
|
-
const factory = handler.getFactory(this.state);
|
|
2132
|
-
if (factory === null) {
|
|
2133
|
-
throw new Error(`Resolver for ${String(this.key)} returned a null factory`);
|
|
2134
|
-
}
|
|
2135
|
-
return factory.construct(requestor);
|
|
2136
|
-
}
|
|
2137
|
-
case 3 /* callback */:
|
|
2138
|
-
return this.state(handler, requestor, this);
|
|
2139
|
-
case 4 /* array */:
|
|
2140
|
-
return this.state[0].resolve(handler, requestor);
|
|
2141
|
-
case 5 /* alias */:
|
|
2142
|
-
return requestor.get(this.state);
|
|
2143
|
-
default:
|
|
2144
|
-
throw new Error(`Invalid resolver strategy specified: ${this.strategy}.`);
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
getFactory(container) {
|
|
2148
|
-
var _a, _b, _c;
|
|
2149
|
-
switch (this.strategy) {
|
|
2150
|
-
case 1 /* singleton */:
|
|
2151
|
-
case 2 /* transient */:
|
|
2152
|
-
return container.getFactory(this.state);
|
|
2153
|
-
case 5 /* alias */:
|
|
2154
|
-
return (_c = (_b = (_a = container.getResolver(this.state)) === null || _a === void 0 ? void 0 : _a.getFactory) === null || _b === void 0 ? void 0 : _b.call(_a, container)) !== null && _c !== void 0 ? _c : null;
|
|
2155
|
-
default:
|
|
2156
|
-
return null;
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
function containerGetKey(d) {
|
|
2161
|
-
return this.get(d);
|
|
2162
|
-
}
|
|
2163
|
-
function transformInstance(inst, transform) {
|
|
2164
|
-
return transform(inst);
|
|
2165
|
-
}
|
|
2166
|
-
/** @internal */
|
|
2167
|
-
class FactoryImpl {
|
|
2168
|
-
constructor(Type, dependencies) {
|
|
2169
|
-
this.Type = Type;
|
|
2170
|
-
this.dependencies = dependencies;
|
|
2171
|
-
this.transformers = null;
|
|
2172
|
-
}
|
|
2173
|
-
construct(container, dynamicDependencies) {
|
|
2174
|
-
let instance;
|
|
2175
|
-
if (dynamicDependencies === void 0) {
|
|
2176
|
-
instance = new this.Type(...this.dependencies.map(containerGetKey, container));
|
|
2177
|
-
} else {
|
|
2178
|
-
instance = new this.Type(...this.dependencies.map(containerGetKey, container), ...dynamicDependencies);
|
|
2179
|
-
}
|
|
2180
|
-
if (this.transformers == null) {
|
|
2181
|
-
return instance;
|
|
2182
|
-
}
|
|
2183
|
-
return this.transformers.reduce(transformInstance, instance);
|
|
2184
|
-
}
|
|
2185
|
-
registerTransformer(transformer) {
|
|
2186
|
-
(this.transformers || (this.transformers = [])).push(transformer);
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
const containerResolver = {
|
|
2190
|
-
$isResolver: true,
|
|
2191
|
-
resolve(handler, requestor) {
|
|
2192
|
-
return requestor;
|
|
2193
|
-
}
|
|
2194
|
-
};
|
|
2195
|
-
function isRegistry(obj) {
|
|
2196
|
-
return typeof obj.register === "function";
|
|
2197
|
-
}
|
|
2198
|
-
function isSelfRegistry(obj) {
|
|
2199
|
-
return isRegistry(obj) && typeof obj.registerInRequestor === "boolean";
|
|
2200
|
-
}
|
|
2201
|
-
function isRegisterInRequester(obj) {
|
|
2202
|
-
return isSelfRegistry(obj) && obj.registerInRequestor;
|
|
2203
|
-
}
|
|
2204
|
-
function isClass(obj) {
|
|
2205
|
-
return obj.prototype !== void 0;
|
|
2206
|
-
}
|
|
2207
|
-
const InstrinsicTypeNames = new Set(["Array", "ArrayBuffer", "Boolean", "DataView", "Date", "Error", "EvalError", "Float32Array", "Float64Array", "Function", "Int8Array", "Int16Array", "Int32Array", "Map", "Number", "Object", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "SharedArrayBuffer", "String", "SyntaxError", "TypeError", "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "URIError", "WeakMap", "WeakSet"]);
|
|
2208
|
-
const DILocateParentEventType = "__DI_LOCATE_PARENT__";
|
|
2209
|
-
const factories = new Map();
|
|
2210
|
-
/**
|
|
2211
|
-
* @internal
|
|
2212
|
-
*/
|
|
2213
|
-
class ContainerImpl {
|
|
2214
|
-
constructor(owner, config) {
|
|
2215
|
-
this.owner = owner;
|
|
2216
|
-
this.config = config;
|
|
2217
|
-
this._parent = void 0;
|
|
2218
|
-
this.registerDepth = 0;
|
|
2219
|
-
this.context = null;
|
|
2220
|
-
if (owner !== null) {
|
|
2221
|
-
owner.$$container$$ = this;
|
|
2222
|
-
}
|
|
2223
|
-
this.resolvers = new Map();
|
|
2224
|
-
this.resolvers.set(Container, containerResolver);
|
|
2225
|
-
if (owner instanceof Node) {
|
|
2226
|
-
owner.addEventListener(DILocateParentEventType, e => {
|
|
2227
|
-
if (e.composedPath()[0] !== this.owner) {
|
|
2228
|
-
e.detail.container = this;
|
|
2229
|
-
e.stopImmediatePropagation();
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
get parent() {
|
|
2235
|
-
if (this._parent === void 0) {
|
|
2236
|
-
this._parent = this.config.parentLocator(this.owner);
|
|
2237
|
-
}
|
|
2238
|
-
return this._parent;
|
|
2239
|
-
}
|
|
2240
|
-
get depth() {
|
|
2241
|
-
return this.parent === null ? 0 : this.parent.depth + 1;
|
|
2242
|
-
}
|
|
2243
|
-
get responsibleForOwnerRequests() {
|
|
2244
|
-
return this.config.responsibleForOwnerRequests;
|
|
2245
|
-
}
|
|
2246
|
-
registerWithContext(context, ...params) {
|
|
2247
|
-
this.context = context;
|
|
2248
|
-
this.register(...params);
|
|
2249
|
-
this.context = null;
|
|
2250
|
-
return this;
|
|
2251
|
-
}
|
|
2252
|
-
register(...params) {
|
|
2253
|
-
if (++this.registerDepth === 100) {
|
|
2254
|
-
throw new Error("Unable to autoregister dependency");
|
|
2255
|
-
// Most likely cause is trying to register a plain object that does not have a
|
|
2256
|
-
// register method and is not a class constructor
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
let current;
|
|
2260
|
-
let keys;
|
|
2261
|
-
let value;
|
|
2262
|
-
let j;
|
|
2263
|
-
let jj;
|
|
2264
|
-
const context = this.context;
|
|
2265
|
-
for (let i = 0, ii = params.length; i < ii; ++i) {
|
|
2266
|
-
current = params[i];
|
|
2267
|
-
if (!isObject(current)) {
|
|
2268
|
-
continue;
|
|
2269
|
-
}
|
|
2270
|
-
if (isRegistry(current)) {
|
|
2271
|
-
current.register(this, context);
|
|
2272
|
-
} else if (isClass(current)) {
|
|
2273
|
-
Registration.singleton(current, current).register(this);
|
|
2274
|
-
} else {
|
|
2275
|
-
keys = Object.keys(current);
|
|
2276
|
-
j = 0;
|
|
2277
|
-
jj = keys.length;
|
|
2278
|
-
for (; j < jj; ++j) {
|
|
2279
|
-
value = current[keys[j]];
|
|
2280
|
-
if (!isObject(value)) {
|
|
2281
|
-
continue;
|
|
2282
|
-
}
|
|
2283
|
-
// note: we could remove this if-branch and call this.register directly
|
|
2284
|
-
// - the extra check is just a perf tweak to create fewer unnecessary arrays by the spread operator
|
|
2285
|
-
if (isRegistry(value)) {
|
|
2286
|
-
value.register(this, context);
|
|
2287
|
-
} else {
|
|
2288
|
-
this.register(value);
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
--this.registerDepth;
|
|
2294
|
-
return this;
|
|
2295
|
-
}
|
|
2296
|
-
registerResolver(key, resolver) {
|
|
2297
|
-
validateKey(key);
|
|
2298
|
-
const resolvers = this.resolvers;
|
|
2299
|
-
const result = resolvers.get(key);
|
|
2300
|
-
if (result == null) {
|
|
2301
|
-
resolvers.set(key, resolver);
|
|
2302
|
-
} else if (result instanceof ResolverImpl && result.strategy === 4 /* array */) {
|
|
2303
|
-
result.state.push(resolver);
|
|
2304
|
-
} else {
|
|
2305
|
-
resolvers.set(key, new ResolverImpl(key, 4 /* array */, [result, resolver]));
|
|
2306
|
-
}
|
|
2307
|
-
return resolver;
|
|
2308
|
-
}
|
|
2309
|
-
registerTransformer(key, transformer) {
|
|
2310
|
-
const resolver = this.getResolver(key);
|
|
2311
|
-
if (resolver == null) {
|
|
2312
|
-
return false;
|
|
2313
|
-
}
|
|
2314
|
-
if (resolver.getFactory) {
|
|
2315
|
-
const factory = resolver.getFactory(this);
|
|
2316
|
-
if (factory == null) {
|
|
2317
|
-
return false;
|
|
2318
|
-
}
|
|
2319
|
-
// This type cast is a bit of a hacky one, necessary due to the duplicity of IResolverLike.
|
|
2320
|
-
// Problem is that that interface's type arg can be of type Key, but the getFactory method only works on
|
|
2321
|
-
// type Constructable. So the return type of that optional method has this additional constraint, which
|
|
2322
|
-
// seems to confuse the type checker.
|
|
2323
|
-
factory.registerTransformer(transformer);
|
|
2324
|
-
return true;
|
|
2325
|
-
}
|
|
2326
|
-
return false;
|
|
2327
|
-
}
|
|
2328
|
-
getResolver(key, autoRegister = true) {
|
|
2329
|
-
validateKey(key);
|
|
2330
|
-
if (key.resolve !== void 0) {
|
|
2331
|
-
return key;
|
|
2332
|
-
}
|
|
2333
|
-
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
|
|
2334
|
-
let current = this;
|
|
2335
|
-
let resolver;
|
|
2336
|
-
while (current != null) {
|
|
2337
|
-
resolver = current.resolvers.get(key);
|
|
2338
|
-
if (resolver == null) {
|
|
2339
|
-
if (current.parent == null) {
|
|
2340
|
-
const handler = isRegisterInRequester(key) ? this : current;
|
|
2341
|
-
return autoRegister ? this.jitRegister(key, handler) : null;
|
|
2342
|
-
}
|
|
2343
|
-
current = current.parent;
|
|
2344
|
-
} else {
|
|
2345
|
-
return resolver;
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2348
|
-
return null;
|
|
2349
|
-
}
|
|
2350
|
-
has(key, searchAncestors = false) {
|
|
2351
|
-
return this.resolvers.has(key) ? true : searchAncestors && this.parent != null ? this.parent.has(key, true) : false;
|
|
2352
|
-
}
|
|
2353
|
-
get(key) {
|
|
2354
|
-
validateKey(key);
|
|
2355
|
-
if (key.$isResolver) {
|
|
2356
|
-
return key.resolve(this, this);
|
|
2357
|
-
}
|
|
2358
|
-
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
|
|
2359
|
-
let current = this;
|
|
2360
|
-
let resolver;
|
|
2361
|
-
while (current != null) {
|
|
2362
|
-
resolver = current.resolvers.get(key);
|
|
2363
|
-
if (resolver == null) {
|
|
2364
|
-
if (current.parent == null) {
|
|
2365
|
-
const handler = isRegisterInRequester(key) ? this : current;
|
|
2366
|
-
resolver = this.jitRegister(key, handler);
|
|
2367
|
-
return resolver.resolve(current, this);
|
|
2368
|
-
}
|
|
2369
|
-
current = current.parent;
|
|
2370
|
-
} else {
|
|
2371
|
-
return resolver.resolve(current, this);
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
throw new Error(`Unable to resolve key: ${key}`);
|
|
2375
|
-
}
|
|
2376
|
-
getAll(key, searchAncestors = false) {
|
|
2377
|
-
validateKey(key);
|
|
2378
|
-
/* eslint-disable-next-line @typescript-eslint/no-this-alias */
|
|
2379
|
-
const requestor = this;
|
|
2380
|
-
let current = requestor;
|
|
2381
|
-
let resolver;
|
|
2382
|
-
if (searchAncestors) {
|
|
2383
|
-
let resolutions = emptyArray;
|
|
2384
|
-
while (current != null) {
|
|
2385
|
-
resolver = current.resolvers.get(key);
|
|
2386
|
-
if (resolver != null) {
|
|
2387
|
-
resolutions = resolutions.concat( /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
|
2388
|
-
buildAllResponse(resolver, current, requestor));
|
|
2389
|
-
}
|
|
2390
|
-
current = current.parent;
|
|
2391
|
-
}
|
|
2392
|
-
return resolutions;
|
|
2393
|
-
} else {
|
|
2394
|
-
while (current != null) {
|
|
2395
|
-
resolver = current.resolvers.get(key);
|
|
2396
|
-
if (resolver == null) {
|
|
2397
|
-
current = current.parent;
|
|
2398
|
-
if (current == null) {
|
|
2399
|
-
return emptyArray;
|
|
2400
|
-
}
|
|
2401
|
-
} else {
|
|
2402
|
-
return buildAllResponse(resolver, current, requestor);
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
return emptyArray;
|
|
2407
|
-
}
|
|
2408
|
-
getFactory(Type) {
|
|
2409
|
-
let factory = factories.get(Type);
|
|
2410
|
-
if (factory === void 0) {
|
|
2411
|
-
if (isNativeFunction(Type)) {
|
|
2412
|
-
throw new Error(`${Type.name} is a native function and therefore cannot be safely constructed by DI. If this is intentional, please use a callback or cachedCallback resolver.`);
|
|
2413
|
-
}
|
|
2414
|
-
factories.set(Type, factory = new FactoryImpl(Type, DI.getDependencies(Type)));
|
|
2415
|
-
}
|
|
2416
|
-
return factory;
|
|
2417
|
-
}
|
|
2418
|
-
registerFactory(key, factory) {
|
|
2419
|
-
factories.set(key, factory);
|
|
2420
|
-
}
|
|
2421
|
-
createChild(config) {
|
|
2422
|
-
return new ContainerImpl(null, Object.assign({}, this.config, config, {
|
|
2423
|
-
parentLocator: () => this
|
|
2424
|
-
}));
|
|
2425
|
-
}
|
|
2426
|
-
jitRegister(keyAsValue, handler) {
|
|
2427
|
-
if (typeof keyAsValue !== "function") {
|
|
2428
|
-
throw new Error(`Attempted to jitRegister something that is not a constructor: '${keyAsValue}'. Did you forget to register this dependency?`);
|
|
2429
|
-
}
|
|
2430
|
-
if (InstrinsicTypeNames.has(keyAsValue.name)) {
|
|
2431
|
-
throw new Error(`Attempted to jitRegister an intrinsic type: ${keyAsValue.name}. Did you forget to add @inject(Key)`);
|
|
2432
|
-
}
|
|
2433
|
-
if (isRegistry(keyAsValue)) {
|
|
2434
|
-
const registrationResolver = keyAsValue.register(handler);
|
|
2435
|
-
if (!(registrationResolver instanceof Object) || registrationResolver.resolve == null) {
|
|
2436
|
-
const newResolver = handler.resolvers.get(keyAsValue);
|
|
2437
|
-
if (newResolver != void 0) {
|
|
2438
|
-
return newResolver;
|
|
2439
|
-
}
|
|
2440
|
-
throw new Error("A valid resolver was not returned from the static register method");
|
|
2441
|
-
}
|
|
2442
|
-
return registrationResolver;
|
|
2443
|
-
} else if (keyAsValue.$isInterface) {
|
|
2444
|
-
throw new Error(`Attempted to jitRegister an interface: ${keyAsValue.friendlyName}`);
|
|
2445
|
-
} else {
|
|
2446
|
-
const resolver = this.config.defaultResolver(keyAsValue, handler);
|
|
2447
|
-
handler.resolvers.set(keyAsValue, resolver);
|
|
2448
|
-
return resolver;
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
}
|
|
2452
|
-
const cache = new WeakMap();
|
|
2453
|
-
function cacheCallbackResult(fun) {
|
|
2454
|
-
return function (handler, requestor, resolver) {
|
|
2455
|
-
if (cache.has(resolver)) {
|
|
2456
|
-
return cache.get(resolver);
|
|
2457
|
-
}
|
|
2458
|
-
const t = fun(handler, requestor, resolver);
|
|
2459
|
-
cache.set(resolver, t);
|
|
2460
|
-
return t;
|
|
2461
|
-
};
|
|
2462
|
-
}
|
|
2463
|
-
/**
|
|
2464
|
-
* You can use the resulting Registration of any of the factory methods
|
|
2465
|
-
* to register with the container.
|
|
2466
|
-
*
|
|
2467
|
-
* @example
|
|
2468
|
-
* ```
|
|
2469
|
-
* class Foo {}
|
|
2470
|
-
* const container = DI.createContainer();
|
|
2471
|
-
* container.register(Registration.instance(Foo, new Foo()));
|
|
2472
|
-
* container.get(Foo);
|
|
2473
|
-
* ```
|
|
2474
|
-
*
|
|
2475
|
-
* @public
|
|
2476
|
-
*/
|
|
2477
|
-
const Registration = Object.freeze({
|
|
2478
|
-
/**
|
|
2479
|
-
* Allows you to pass an instance.
|
|
2480
|
-
* Every time you request this {@link Key} you will get this instance back.
|
|
2481
|
-
*
|
|
2482
|
-
* @example
|
|
2483
|
-
* ```
|
|
2484
|
-
* Registration.instance(Foo, new Foo()));
|
|
2485
|
-
* ```
|
|
2486
|
-
*
|
|
2487
|
-
* @param key - The key to register the instance under.
|
|
2488
|
-
* @param value - The instance to return when the key is requested.
|
|
2489
|
-
*/
|
|
2490
|
-
instance(key, value) {
|
|
2491
|
-
return new ResolverImpl(key, 0 /* instance */, value);
|
|
2492
|
-
},
|
|
2493
|
-
/**
|
|
2494
|
-
* Creates an instance from the class.
|
|
2495
|
-
* Every time you request this {@link Key} you will get the same one back.
|
|
2496
|
-
*
|
|
2497
|
-
* @example
|
|
2498
|
-
* ```
|
|
2499
|
-
* Registration.singleton(Foo, Foo);
|
|
2500
|
-
* ```
|
|
2501
|
-
*
|
|
2502
|
-
* @param key - The key to register the singleton under.
|
|
2503
|
-
* @param value - The class to instantiate as a singleton when first requested.
|
|
2504
|
-
*/
|
|
2505
|
-
singleton(key, value) {
|
|
2506
|
-
return new ResolverImpl(key, 1 /* singleton */, value);
|
|
2507
|
-
},
|
|
2508
|
-
/**
|
|
2509
|
-
* Creates an instance from a class.
|
|
2510
|
-
* Every time you request this {@link Key} you will get a new instance.
|
|
2511
|
-
*
|
|
2512
|
-
* @example
|
|
2513
|
-
* ```
|
|
2514
|
-
* Registration.instance(Foo, Foo);
|
|
2515
|
-
* ```
|
|
2516
|
-
*
|
|
2517
|
-
* @param key - The key to register the instance type under.
|
|
2518
|
-
* @param value - The class to instantiate each time the key is requested.
|
|
2519
|
-
*/
|
|
2520
|
-
transient(key, value) {
|
|
2521
|
-
return new ResolverImpl(key, 2 /* transient */, value);
|
|
2522
|
-
},
|
|
2523
|
-
/**
|
|
2524
|
-
* Delegates to a callback function to provide the dependency.
|
|
2525
|
-
* Every time you request this {@link Key} the callback will be invoked to provide
|
|
2526
|
-
* the dependency.
|
|
2527
|
-
*
|
|
2528
|
-
* @example
|
|
2529
|
-
* ```
|
|
2530
|
-
* Registration.callback(Foo, () => new Foo());
|
|
2531
|
-
* Registration.callback(Bar, (c: Container) => new Bar(c.get(Foo)));
|
|
2532
|
-
* ```
|
|
2533
|
-
*
|
|
2534
|
-
* @param key - The key to register the callback for.
|
|
2535
|
-
* @param callback - The function that is expected to return the dependency.
|
|
2536
|
-
*/
|
|
2537
|
-
callback(key, callback) {
|
|
2538
|
-
return new ResolverImpl(key, 3 /* callback */, callback);
|
|
2539
|
-
},
|
|
2540
|
-
/**
|
|
2541
|
-
* Delegates to a callback function to provide the dependency and then caches the
|
|
2542
|
-
* dependency for future requests.
|
|
2543
|
-
*
|
|
2544
|
-
* @example
|
|
2545
|
-
* ```
|
|
2546
|
-
* Registration.cachedCallback(Foo, () => new Foo());
|
|
2547
|
-
* Registration.cachedCallback(Bar, (c: Container) => new Bar(c.get(Foo)));
|
|
2548
|
-
* ```
|
|
2549
|
-
*
|
|
2550
|
-
* @param key - The key to register the callback for.
|
|
2551
|
-
* @param callback - The function that is expected to return the dependency.
|
|
2552
|
-
* @remarks
|
|
2553
|
-
* If you pass the same Registration to another container, the same cached value will be used.
|
|
2554
|
-
* Should all references to the resolver returned be removed, the cache will expire.
|
|
2555
|
-
*/
|
|
2556
|
-
cachedCallback(key, callback) {
|
|
2557
|
-
return new ResolverImpl(key, 3 /* callback */, cacheCallbackResult(callback));
|
|
2558
|
-
},
|
|
2559
|
-
/**
|
|
2560
|
-
* Creates an alternate {@link Key} to retrieve an instance by.
|
|
2561
|
-
*
|
|
2562
|
-
* @example
|
|
2563
|
-
* ```
|
|
2564
|
-
* Register.singleton(Foo, Foo)
|
|
2565
|
-
* Register.aliasTo(Foo, MyFoos);
|
|
2566
|
-
*
|
|
2567
|
-
* container.getAll(MyFoos) // contains an instance of Foo
|
|
2568
|
-
* ```
|
|
2569
|
-
*
|
|
2570
|
-
* @param originalKey - The original key that has been registered.
|
|
2571
|
-
* @param aliasKey - The alias to the original key.
|
|
2572
|
-
*/
|
|
2573
|
-
aliasTo(originalKey, aliasKey) {
|
|
2574
|
-
return new ResolverImpl(aliasKey, 5 /* alias */, originalKey);
|
|
2575
|
-
}
|
|
2576
|
-
});
|
|
2577
|
-
/** @internal */
|
|
2578
|
-
function validateKey(key) {
|
|
2579
|
-
if (key === null || key === void 0) {
|
|
2580
|
-
throw new Error("key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?");
|
|
2581
|
-
}
|
|
2582
|
-
}
|
|
2583
|
-
function buildAllResponse(resolver, handler, requestor) {
|
|
2584
|
-
if (resolver instanceof ResolverImpl && resolver.strategy === 4 /* array */) {
|
|
2585
|
-
const state = resolver.state;
|
|
2586
|
-
let i = state.length;
|
|
2587
|
-
const results = new Array(i);
|
|
2588
|
-
while (i--) {
|
|
2589
|
-
results[i] = state[i].resolve(handler, requestor);
|
|
2590
|
-
}
|
|
2591
|
-
return results;
|
|
2592
|
-
}
|
|
2593
|
-
return [resolver.resolve(handler, requestor)];
|
|
2594
|
-
}
|
|
2595
|
-
const defaultFriendlyName = "(anonymous)";
|
|
2596
|
-
function isObject(value) {
|
|
2597
|
-
return typeof value === "object" && value !== null || typeof value === "function";
|
|
2598
|
-
}
|
|
2599
|
-
/**
|
|
2600
|
-
* Determine whether the value is a native function.
|
|
2601
|
-
*
|
|
2602
|
-
* @param fn - The function to check.
|
|
2603
|
-
* @returns `true` is the function is a native function, otherwise `false`
|
|
2604
|
-
*/
|
|
2605
|
-
const isNativeFunction = function () {
|
|
2606
|
-
const lookup = new WeakMap();
|
|
2607
|
-
let isNative = false;
|
|
2608
|
-
let sourceText = "";
|
|
2609
|
-
let i = 0;
|
|
2610
|
-
return function (fn) {
|
|
2611
|
-
isNative = lookup.get(fn);
|
|
2612
|
-
if (isNative === void 0) {
|
|
2613
|
-
sourceText = fn.toString();
|
|
2614
|
-
i = sourceText.length;
|
|
2615
|
-
// http://www.ecma-international.org/ecma-262/#prod-NativeFunction
|
|
2616
|
-
isNative =
|
|
2617
|
-
// 29 is the length of 'function () { [native code] }' which is the smallest length of a native function string
|
|
2618
|
-
i >= 29 &&
|
|
2619
|
-
// 100 seems to be a safe upper bound of the max length of a native function. In Chrome and FF it's 56, in Edge it's 61.
|
|
2620
|
-
i <= 100 &&
|
|
2621
|
-
// This whole heuristic *could* be tricked by a comment. Do we need to care about that?
|
|
2622
|
-
sourceText.charCodeAt(i - 1) === 0x7d &&
|
|
2623
|
-
// }
|
|
2624
|
-
// TODO: the spec is a little vague about the precise constraints, so we do need to test this across various browsers to make sure just one whitespace is a safe assumption.
|
|
2625
|
-
sourceText.charCodeAt(i - 2) <= 0x20 &&
|
|
2626
|
-
// whitespace
|
|
2627
|
-
sourceText.charCodeAt(i - 3) === 0x5d &&
|
|
2628
|
-
// ]
|
|
2629
|
-
sourceText.charCodeAt(i - 4) === 0x65 &&
|
|
2630
|
-
// e
|
|
2631
|
-
sourceText.charCodeAt(i - 5) === 0x64 &&
|
|
2632
|
-
// d
|
|
2633
|
-
sourceText.charCodeAt(i - 6) === 0x6f &&
|
|
2634
|
-
// o
|
|
2635
|
-
sourceText.charCodeAt(i - 7) === 0x63 &&
|
|
2636
|
-
// c
|
|
2637
|
-
sourceText.charCodeAt(i - 8) === 0x20 &&
|
|
2638
|
-
//
|
|
2639
|
-
sourceText.charCodeAt(i - 9) === 0x65 &&
|
|
2640
|
-
// e
|
|
2641
|
-
sourceText.charCodeAt(i - 10) === 0x76 &&
|
|
2642
|
-
// v
|
|
2643
|
-
sourceText.charCodeAt(i - 11) === 0x69 &&
|
|
2644
|
-
// i
|
|
2645
|
-
sourceText.charCodeAt(i - 12) === 0x74 &&
|
|
2646
|
-
// t
|
|
2647
|
-
sourceText.charCodeAt(i - 13) === 0x61 &&
|
|
2648
|
-
// a
|
|
2649
|
-
sourceText.charCodeAt(i - 14) === 0x6e &&
|
|
2650
|
-
// n
|
|
2651
|
-
sourceText.charCodeAt(i - 15) === 0x58; // [
|
|
2652
|
-
lookup.set(fn, isNative);
|
|
2653
|
-
}
|
|
2654
|
-
return isNative;
|
|
2655
|
-
};
|
|
2656
|
-
}();
|
|
2657
|
-
const isNumericLookup = {};
|
|
2658
|
-
function isArrayIndex(value) {
|
|
2659
|
-
switch (typeof value) {
|
|
2660
|
-
case "number":
|
|
2661
|
-
return value >= 0 && (value | 0) === value;
|
|
2662
|
-
case "string":
|
|
2663
|
-
{
|
|
2664
|
-
const result = isNumericLookup[value];
|
|
2665
|
-
if (result !== void 0) {
|
|
2666
|
-
return result;
|
|
2667
|
-
}
|
|
2668
|
-
const length = value.length;
|
|
2669
|
-
if (length === 0) {
|
|
2670
|
-
return isNumericLookup[value] = false;
|
|
2671
|
-
}
|
|
2672
|
-
let ch = 0;
|
|
2673
|
-
for (let i = 0; i < length; ++i) {
|
|
2674
|
-
ch = value.charCodeAt(i);
|
|
2675
|
-
if (i === 0 && ch === 0x30 && length > 1 /* must not start with 0 */ || ch < 0x30 /* 0 */ || ch > 0x39 /* 9 */) {
|
|
2676
|
-
return isNumericLookup[value] = false;
|
|
2677
|
-
}
|
|
2678
|
-
}
|
|
2679
|
-
return isNumericLookup[value] = true;
|
|
2680
|
-
}
|
|
2681
|
-
default:
|
|
2682
|
-
return false;
|
|
2683
|
-
}
|
|
2684
|
-
}
|
|
2685
|
-
|
|
2686
|
-
const isEmitOptions = candidate => (candidate === null || candidate === void 0 ? void 0 : candidate.hasOwnProperty('bubbles')) || (candidate === null || candidate === void 0 ? void 0 : candidate.hasOwnProperty('cancelable')) || (candidate === null || candidate === void 0 ? void 0 : candidate.hasOwnProperty('composed'));
|
|
2687
|
-
const getBaseEmitArgs = (...args) => {
|
|
2688
|
-
let [type, detailOrOptions, options] = args;
|
|
2689
|
-
let detail = detailOrOptions;
|
|
2690
|
-
if (isEmitOptions(detailOrOptions)) {
|
|
2691
|
-
options = detailOrOptions;
|
|
2692
|
-
detail = undefined;
|
|
2693
|
-
}
|
|
2694
|
-
if (typeof type !== 'string') {
|
|
2695
|
-
throw new Error('$emit event types must be typeof string.');
|
|
2696
|
-
}
|
|
2697
|
-
return [type, detail, options];
|
|
2698
|
-
};
|
|
2699
|
-
const customEvent = ctx => ctx.event;
|
|
2700
|
-
const targetValue = ctx => ctx.event.target.value;
|
|
2701
|
-
const targetFirstSelectedValue = ctx => {
|
|
2702
|
-
var _a, _b;
|
|
2703
|
-
return (_b = (_a = ctx.event.target) === null || _a === void 0 ? void 0 : _a.firstSelectedOption) === null || _b === void 0 ? void 0 : _b.value;
|
|
2704
|
-
};
|
|
2705
|
-
const createChangeEmitter = valueGetter => (type, options) => (x, c) => x.$emit(String(type), valueGetter(c), options);
|
|
2706
|
-
const createInputEmitter = () => createChangeEmitter(targetValue);
|
|
2707
|
-
const createSelectEmitter = () => createChangeEmitter(targetFirstSelectedValue);
|
|
2708
|
-
|
|
2709
|
-
class DefaultEventEmitterDI {
|
|
2710
|
-
emit(...args) {
|
|
2711
|
-
const [origin, ...rest] = args;
|
|
2712
|
-
const [type, detail, options] = getBaseEmitArgs(...rest);
|
|
2713
|
-
return origin.$emit(type, detail, options);
|
|
2714
|
-
}
|
|
2715
|
-
}
|
|
2716
|
-
const EventEmitterDI = DI.createInterface(x => x.singleton(DefaultEventEmitterDI));
|
|
2717
|
-
const registerEmitter = () => {
|
|
2718
|
-
return DI.createInterface(x => x.aliasTo(EventEmitterDI));
|
|
2719
|
-
};
|
|
2720
|
-
|
|
2721
|
-
const EventEmitter = Base => class extends Base {
|
|
2722
|
-
$emit(...args) {
|
|
2723
|
-
const [type, detail, options] = getBaseEmitArgs(...args);
|
|
2724
|
-
return super.$emit(type, detail, options);
|
|
2725
|
-
}
|
|
2726
|
-
};
|
|
2727
|
-
|
|
2728
|
-
export { DefaultEventEmitterDI, EventEmitter, EventEmitterDI, createInputEmitter, createSelectEmitter, customEvent, getBaseEmitArgs, registerEmitter, targetFirstSelectedValue, targetValue };
|