@angular/core 17.0.0-next.2 → 17.0.0-next.3
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/esm2022/src/core_render3_private_export.mjs +2 -2
- package/esm2022/src/hydration/annotate.mjs +9 -6
- package/esm2022/src/hydration/cleanup.mjs +2 -2
- package/esm2022/src/linker/template_ref.mjs +3 -3
- package/esm2022/src/linker/view_container_ref.mjs +80 -25
- package/esm2022/src/render3/after_render_hooks.mjs +69 -41
- package/esm2022/src/render3/component.mjs +4 -3
- package/esm2022/src/render3/di.mjs +1 -1
- package/esm2022/src/render3/index.mjs +2 -2
- package/esm2022/src/render3/instructions/all.mjs +2 -1
- package/esm2022/src/render3/instructions/change_detection.mjs +5 -6
- package/esm2022/src/render3/instructions/component_instance.mjs +23 -0
- package/esm2022/src/render3/instructions/control_flow.mjs +20 -4
- package/esm2022/src/render3/instructions/defer.mjs +100 -39
- package/esm2022/src/render3/instructions/shared.mjs +20 -14
- package/esm2022/src/render3/interfaces/defer.mjs +1 -1
- package/esm2022/src/render3/interfaces/injector.mjs +1 -1
- package/esm2022/src/render3/interfaces/node.mjs +16 -1
- package/esm2022/src/render3/interfaces/styling.mjs +4 -7
- package/esm2022/src/render3/jit/environment.mjs +2 -1
- package/esm2022/src/render3/node_manipulation.mjs +4 -3
- package/esm2022/src/render3/reactive_lview_consumer.mjs +25 -45
- package/esm2022/src/render3/reactivity/effect.mjs +8 -8
- package/esm2022/src/render3/util/injector_utils.mjs +1 -1
- package/esm2022/src/render3/view_manipulation.mjs +13 -2
- package/esm2022/src/signals/index.mjs +4 -4
- package/esm2022/src/signals/src/api.mjs +2 -11
- package/esm2022/src/signals/src/computed.mjs +43 -93
- package/esm2022/src/signals/src/graph.mjs +238 -162
- package/esm2022/src/signals/src/signal.mjs +59 -79
- package/esm2022/src/signals/src/watch.mjs +38 -52
- package/esm2022/src/signals/src/weak_ref.mjs +2 -29
- package/esm2022/src/util/security/trusted_type_defs.mjs +1 -1
- package/esm2022/src/util/security/trusted_types.mjs +1 -1
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/src/zone/ng_zone.mjs +16 -1
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +1977 -1815
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +143 -125
- package/package.json +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/ng-generate/standalone-migration/bundle.js +192 -53
- package/schematics/ng-generate/standalone-migration/bundle.js.map +3 -3
- package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.0.0-next.
|
|
2
|
+
* @license Angular v17.0.0-next.3
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -2273,15 +2273,6 @@ const SIGNAL = Symbol('SIGNAL');
|
|
|
2273
2273
|
function isSignal(value) {
|
|
2274
2274
|
return typeof value === 'function' && value[SIGNAL] !== undefined;
|
|
2275
2275
|
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Converts `fn` into a marked signal function (where `isSignal(fn)` will be `true`), and
|
|
2278
|
-
* potentially add some set of extra properties (passed as an object record `extraApi`).
|
|
2279
|
-
*/
|
|
2280
|
-
function createSignalFromFunction(node, fn, extraApi = {}) {
|
|
2281
|
-
fn[SIGNAL] = node;
|
|
2282
|
-
// Copy properties from `extraApi` to `fn` to complete the desired API of the `Signal`.
|
|
2283
|
-
return Object.assign(fn, extraApi);
|
|
2284
|
-
}
|
|
2285
2276
|
/**
|
|
2286
2277
|
* The default equality function used for `signal` and `computed`, which treats objects and arrays
|
|
2287
2278
|
* as never equal, and all other primitive values using identity semantics.
|
|
@@ -2302,216 +2293,265 @@ function defaultEquals(a, b) {
|
|
|
2302
2293
|
|
|
2303
2294
|
// Required as the signals library is in a separate package, so we need to explicitly ensure the
|
|
2304
2295
|
/**
|
|
2305
|
-
*
|
|
2306
|
-
*
|
|
2296
|
+
* The currently active consumer `ReactiveNode`, if running code in a reactive context.
|
|
2297
|
+
*
|
|
2298
|
+
* Change this via `setActiveConsumer`.
|
|
2299
|
+
*/
|
|
2300
|
+
let activeConsumer = null;
|
|
2301
|
+
let inNotificationPhase = false;
|
|
2302
|
+
function setActiveConsumer(consumer) {
|
|
2303
|
+
const prev = activeConsumer;
|
|
2304
|
+
activeConsumer = consumer;
|
|
2305
|
+
return prev;
|
|
2306
|
+
}
|
|
2307
|
+
const REACTIVE_NODE = {
|
|
2308
|
+
version: 0,
|
|
2309
|
+
dirty: false,
|
|
2310
|
+
producerNode: undefined,
|
|
2311
|
+
producerLastReadVersion: undefined,
|
|
2312
|
+
producerIndexOfThis: undefined,
|
|
2313
|
+
nextProducerIndex: 0,
|
|
2314
|
+
liveConsumerNode: undefined,
|
|
2315
|
+
liveConsumerIndexOfThis: undefined,
|
|
2316
|
+
consumerAllowSignalWrites: false,
|
|
2317
|
+
consumerIsAlwaysLive: false,
|
|
2318
|
+
producerMustRecompute: () => false,
|
|
2319
|
+
producerRecomputeValue: () => { },
|
|
2320
|
+
consumerMarkedDirty: () => { },
|
|
2321
|
+
};
|
|
2322
|
+
/**
|
|
2323
|
+
* Called by implementations when a producer's signal is read.
|
|
2307
2324
|
*/
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2325
|
+
function producerAccessed(node) {
|
|
2326
|
+
if (inNotificationPhase) {
|
|
2327
|
+
throw new Error(typeof ngDevMode !== 'undefined' && ngDevMode ?
|
|
2328
|
+
`Assertion error: signal read during notification phase` :
|
|
2329
|
+
'');
|
|
2311
2330
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2331
|
+
if (activeConsumer === null) {
|
|
2332
|
+
// Accessed outside of a reactive context, so nothing to record.
|
|
2333
|
+
return;
|
|
2314
2334
|
}
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2335
|
+
// This producer is the `idx`th dependency of `activeConsumer`.
|
|
2336
|
+
const idx = activeConsumer.nextProducerIndex++;
|
|
2337
|
+
assertConsumerNode(activeConsumer);
|
|
2338
|
+
if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {
|
|
2339
|
+
// There's been a change in producers since the last execution of `activeConsumer`.
|
|
2340
|
+
// `activeConsumer.producerNode[idx]` holds a stale dependency which will be be removed and
|
|
2341
|
+
// replaced with `this`.
|
|
2342
|
+
//
|
|
2343
|
+
// If `activeConsumer` isn't live, then this is a no-op, since we can replace the producer in
|
|
2344
|
+
// `activeConsumer.producerNode` directly. However, if `activeConsumer` is live, then we need
|
|
2345
|
+
// to remove it from the stale producer's `liveConsumer`s.
|
|
2346
|
+
if (consumerIsLive(activeConsumer)) {
|
|
2347
|
+
const staleProducer = activeConsumer.producerNode[idx];
|
|
2348
|
+
producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);
|
|
2349
|
+
// At this point, the only record of `staleProducer` is the reference at
|
|
2350
|
+
// `activeConsumer.producerNode[idx]` which will be overwritten below.
|
|
2351
|
+
}
|
|
2323
2352
|
}
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2353
|
+
if (activeConsumer.producerNode[idx] !== node) {
|
|
2354
|
+
// We're a new dependency of the consumer (at `idx`).
|
|
2355
|
+
activeConsumer.producerNode[idx] = node;
|
|
2356
|
+
// If the active consumer is live, then add it as a live consumer. If not, then use 0 as a
|
|
2357
|
+
// placeholder value.
|
|
2358
|
+
activeConsumer.producerIndexOfThis[idx] =
|
|
2359
|
+
consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
|
|
2360
|
+
}
|
|
2361
|
+
activeConsumer.producerLastReadVersion[idx] = node.version;
|
|
2329
2362
|
}
|
|
2330
|
-
|
|
2331
|
-
// Required as the signals library is in a separate package, so we need to explicitly ensure the
|
|
2332
2363
|
/**
|
|
2333
|
-
*
|
|
2364
|
+
* Ensure this producer's `version` is up-to-date.
|
|
2334
2365
|
*/
|
|
2335
|
-
|
|
2366
|
+
function producerUpdateValueVersion(node) {
|
|
2367
|
+
if (consumerIsLive(node) && !node.dirty) {
|
|
2368
|
+
// A live consumer will be marked dirty by producers, so a clean state means that its version
|
|
2369
|
+
// is guaranteed to be up-to-date.
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {
|
|
2373
|
+
// None of our producers report a change since the last time they were read, so no
|
|
2374
|
+
// recomputation of our value is necessary, and we can consider ourselves clean.
|
|
2375
|
+
node.dirty = false;
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
node.producerRecomputeValue(node);
|
|
2379
|
+
// After recomputing the value, we're no longer dirty.
|
|
2380
|
+
node.dirty = false;
|
|
2381
|
+
}
|
|
2336
2382
|
/**
|
|
2337
|
-
*
|
|
2338
|
-
* consumer).
|
|
2383
|
+
* Propagate a dirty notification to live consumers of this producer.
|
|
2339
2384
|
*/
|
|
2340
|
-
|
|
2385
|
+
function producerNotifyConsumers(node) {
|
|
2386
|
+
if (node.liveConsumerNode === undefined) {
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
// Prevent signal reads when we're updating the graph
|
|
2390
|
+
const prev = inNotificationPhase;
|
|
2391
|
+
inNotificationPhase = true;
|
|
2392
|
+
try {
|
|
2393
|
+
for (const consumer of node.liveConsumerNode) {
|
|
2394
|
+
if (!consumer.dirty) {
|
|
2395
|
+
consumerMarkDirty(consumer);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
finally {
|
|
2400
|
+
inNotificationPhase = prev;
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2341
2403
|
/**
|
|
2342
|
-
* Whether
|
|
2404
|
+
* Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
|
|
2405
|
+
* based on the current consumer context.
|
|
2343
2406
|
*/
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2407
|
+
function producerUpdatesAllowed() {
|
|
2408
|
+
return activeConsumer?.consumerAllowSignalWrites !== false;
|
|
2409
|
+
}
|
|
2410
|
+
function consumerMarkDirty(node) {
|
|
2411
|
+
node.dirty = true;
|
|
2412
|
+
producerNotifyConsumers(node);
|
|
2413
|
+
node.consumerMarkedDirty?.(node);
|
|
2349
2414
|
}
|
|
2350
2415
|
/**
|
|
2351
|
-
*
|
|
2352
|
-
*
|
|
2353
|
-
* Nodes can be producers of reactive values, consumers of other reactive values, or both.
|
|
2354
|
-
*
|
|
2355
|
-
* Producers are nodes that produce values, and can be depended upon by consumer nodes.
|
|
2356
|
-
*
|
|
2357
|
-
* Producers expose a monotonic `valueVersion` counter, and are responsible for incrementing this
|
|
2358
|
-
* version when their value semantically changes. Some producers may produce their values lazily and
|
|
2359
|
-
* thus at times need to be polled for potential updates to their value (and by extension their
|
|
2360
|
-
* `valueVersion`). This is accomplished via the `onProducerUpdateValueVersion` method for
|
|
2361
|
-
* implemented by producers, which should perform whatever calculations are necessary to ensure
|
|
2362
|
-
* `valueVersion` is up to date.
|
|
2416
|
+
* Prepare this consumer to run a computation in its reactive context.
|
|
2363
2417
|
*
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
*
|
|
2373
|
-
* reads it needs and establish a new set of dependencies as a result.
|
|
2418
|
+
* Must be called by subclasses which represent reactive computations, before those computations
|
|
2419
|
+
* begin.
|
|
2420
|
+
*/
|
|
2421
|
+
function consumerBeforeComputation(node) {
|
|
2422
|
+
node && (node.nextProducerIndex = 0);
|
|
2423
|
+
return setActiveConsumer(node);
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Finalize this consumer's state after a reactive computation has run.
|
|
2374
2427
|
*
|
|
2375
|
-
*
|
|
2376
|
-
*
|
|
2377
|
-
* comparing the consumer's `trackingVersion` to the version at which the dependency was
|
|
2378
|
-
* last observed.
|
|
2428
|
+
* Must be called by subclasses which represent reactive computations, after those computations
|
|
2429
|
+
* have finished.
|
|
2379
2430
|
*/
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
*/
|
|
2386
|
-
this.ref = newWeakRef(this);
|
|
2387
|
-
/**
|
|
2388
|
-
* Edges to producers on which this node depends (in its consumer capacity).
|
|
2389
|
-
*/
|
|
2390
|
-
this.producers = new Map();
|
|
2391
|
-
/**
|
|
2392
|
-
* Edges to consumers on which this node depends (in its producer capacity).
|
|
2393
|
-
*/
|
|
2394
|
-
this.consumers = new Map();
|
|
2395
|
-
/**
|
|
2396
|
-
* Monotonically increasing counter representing a version of this `Consumer`'s
|
|
2397
|
-
* dependencies.
|
|
2398
|
-
*/
|
|
2399
|
-
this.trackingVersion = 0;
|
|
2400
|
-
/**
|
|
2401
|
-
* Monotonically increasing counter which increases when the value of this `Producer`
|
|
2402
|
-
* semantically changes.
|
|
2403
|
-
*/
|
|
2404
|
-
this.valueVersion = 0;
|
|
2431
|
+
function consumerAfterComputation(node, prevConsumer) {
|
|
2432
|
+
setActiveConsumer(prevConsumer);
|
|
2433
|
+
if (!node || node.producerNode === undefined || node.producerIndexOfThis === undefined ||
|
|
2434
|
+
node.producerLastReadVersion === undefined) {
|
|
2435
|
+
return;
|
|
2405
2436
|
}
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
* rerun any reactions.
|
|
2412
|
-
*/
|
|
2413
|
-
consumerPollProducersForChange() {
|
|
2414
|
-
for (const [producerId, edge] of this.producers) {
|
|
2415
|
-
const producer = edge.producerNode.deref();
|
|
2416
|
-
// On Safari < 16.1 deref can return null, we need to check for null also.
|
|
2417
|
-
// See https://github.com/WebKit/WebKit/commit/44c15ba58912faab38b534fef909dd9e13e095e0
|
|
2418
|
-
if (producer == null || edge.atTrackingVersion !== this.trackingVersion) {
|
|
2419
|
-
// This dependency edge is stale, so remove it.
|
|
2420
|
-
this.producers.delete(producerId);
|
|
2421
|
-
producer?.consumers.delete(this.id);
|
|
2422
|
-
continue;
|
|
2423
|
-
}
|
|
2424
|
-
if (producer.producerPollStatus(edge.seenValueVersion)) {
|
|
2425
|
-
// One of the dependencies reports a real value change.
|
|
2426
|
-
return true;
|
|
2427
|
-
}
|
|
2437
|
+
if (consumerIsLive(node)) {
|
|
2438
|
+
// For live consumers, we need to remove the producer -> consumer edge for any stale producers
|
|
2439
|
+
// which weren't dependencies after the recomputation.
|
|
2440
|
+
for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
|
|
2441
|
+
producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
|
|
2428
2442
|
}
|
|
2429
|
-
// No dependency reported a real value change, so the `Consumer` has also not been
|
|
2430
|
-
// impacted.
|
|
2431
|
-
return false;
|
|
2432
2443
|
}
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
const prev = inNotificationPhase;
|
|
2439
|
-
inNotificationPhase = true;
|
|
2440
|
-
try {
|
|
2441
|
-
for (const [consumerId, edge] of this.consumers) {
|
|
2442
|
-
const consumer = edge.consumerNode.deref();
|
|
2443
|
-
// On Safari < 16.1 deref can return null, we need to check for null also.
|
|
2444
|
-
// See https://github.com/WebKit/WebKit/commit/44c15ba58912faab38b534fef909dd9e13e095e0
|
|
2445
|
-
if (consumer == null || consumer.trackingVersion !== edge.atTrackingVersion) {
|
|
2446
|
-
this.consumers.delete(consumerId);
|
|
2447
|
-
consumer?.producers.delete(this.id);
|
|
2448
|
-
continue;
|
|
2449
|
-
}
|
|
2450
|
-
consumer.onConsumerDependencyMayHaveChanged();
|
|
2451
|
-
}
|
|
2452
|
-
}
|
|
2453
|
-
finally {
|
|
2454
|
-
inNotificationPhase = prev;
|
|
2455
|
-
}
|
|
2444
|
+
// Truncate the producer tracking arrays.
|
|
2445
|
+
for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
|
|
2446
|
+
node.producerNode.pop();
|
|
2447
|
+
node.producerLastReadVersion.pop();
|
|
2448
|
+
node.producerIndexOfThis.pop();
|
|
2456
2449
|
}
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2450
|
+
}
|
|
2451
|
+
/**
|
|
2452
|
+
* Determine whether this consumer has any dependencies which have changed since the last time
|
|
2453
|
+
* they were read.
|
|
2454
|
+
*/
|
|
2455
|
+
function consumerPollProducersForChange(node) {
|
|
2456
|
+
assertConsumerNode(node);
|
|
2457
|
+
// Poll producers for change.
|
|
2458
|
+
for (let i = 0; i < node.producerNode.length; i++) {
|
|
2459
|
+
const producer = node.producerNode[i];
|
|
2460
|
+
const seenVersion = node.producerLastReadVersion[i];
|
|
2461
|
+
// First check the versions. A mismatch means that the producer's value is known to have
|
|
2462
|
+
// changed since the last time we read it.
|
|
2463
|
+
if (seenVersion !== producer.version) {
|
|
2464
|
+
return true;
|
|
2468
2465
|
}
|
|
2469
|
-
//
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
atTrackingVersion: activeConsumer.trackingVersion,
|
|
2477
|
-
};
|
|
2478
|
-
activeConsumer.producers.set(this.id, edge);
|
|
2479
|
-
this.consumers.set(activeConsumer.id, edge);
|
|
2466
|
+
// The producer's version is the same as the last time we read it, but it might itself be
|
|
2467
|
+
// stale. Force the producer to recompute its version (calculating a new value if necessary).
|
|
2468
|
+
producerUpdateValueVersion(producer);
|
|
2469
|
+
// Now when we do this check, `producer.version` is guaranteed to be up to date, so if the
|
|
2470
|
+
// versions still match then it has not changed since the last time we read it.
|
|
2471
|
+
if (seenVersion !== producer.version) {
|
|
2472
|
+
return true;
|
|
2480
2473
|
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2474
|
+
}
|
|
2475
|
+
return false;
|
|
2476
|
+
}
|
|
2477
|
+
/**
|
|
2478
|
+
* Disconnect this consumer from the graph.
|
|
2479
|
+
*/
|
|
2480
|
+
function consumerDestroy(node) {
|
|
2481
|
+
assertConsumerNode(node);
|
|
2482
|
+
if (consumerIsLive(node)) {
|
|
2483
|
+
// Drop all connections from the graph to this node.
|
|
2484
|
+
for (let i = 0; i < node.producerNode.length; i++) {
|
|
2485
|
+
producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
|
|
2484
2486
|
}
|
|
2485
2487
|
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2488
|
+
// Truncate all the arrays to drop all connection from this node to the graph.
|
|
2489
|
+
node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length =
|
|
2490
|
+
0;
|
|
2491
|
+
if (node.liveConsumerNode) {
|
|
2492
|
+
node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
|
|
2491
2493
|
}
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2494
|
+
}
|
|
2495
|
+
/**
|
|
2496
|
+
* Add `consumer` as a live consumer of this node.
|
|
2497
|
+
*
|
|
2498
|
+
* Note that this operation is potentially transitive. If this node becomes live, then it becomes
|
|
2499
|
+
* a live consumer of all of its current producers.
|
|
2500
|
+
*/
|
|
2501
|
+
function producerAddLiveConsumer(node, consumer, indexOfThis) {
|
|
2502
|
+
assertProducerNode(node);
|
|
2503
|
+
assertConsumerNode(node);
|
|
2504
|
+
if (node.liveConsumerNode.length === 0) {
|
|
2505
|
+
// When going from 0 to 1 live consumers, we become a live consumer to our producers.
|
|
2506
|
+
for (let i = 0; i < node.producerNode.length; i++) {
|
|
2507
|
+
node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
|
|
2508
|
+
}
|
|
2498
2509
|
}
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2510
|
+
node.liveConsumerIndexOfThis.push(indexOfThis);
|
|
2511
|
+
return node.liveConsumerNode.push(consumer) - 1;
|
|
2512
|
+
}
|
|
2513
|
+
/**
|
|
2514
|
+
* Remove the live consumer at `idx`.
|
|
2515
|
+
*/
|
|
2516
|
+
function producerRemoveLiveConsumerAtIndex(node, idx) {
|
|
2517
|
+
assertProducerNode(node);
|
|
2518
|
+
assertConsumerNode(node);
|
|
2519
|
+
if (node.liveConsumerNode.length === 1) {
|
|
2520
|
+
// When removing the last live consumer, we will no longer be live. We need to remove
|
|
2521
|
+
// ourselves from our producers' tracking (which may cause consumer-producers to lose
|
|
2522
|
+
// liveness as well).
|
|
2523
|
+
for (let i = 0; i < node.producerNode.length; i++) {
|
|
2524
|
+
producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
|
|
2509
2525
|
}
|
|
2510
|
-
// Trigger the `Producer` to update its `valueVersion` if necessary.
|
|
2511
|
-
this.onProducerUpdateValueVersion();
|
|
2512
|
-
// At this point, we can trust `producer.valueVersion`.
|
|
2513
|
-
return this.valueVersion !== lastSeenValueVersion;
|
|
2514
2526
|
}
|
|
2527
|
+
// Move the last value of `liveConsumers` into `idx`. Note that if there's only a single
|
|
2528
|
+
// live consumer, this is a no-op.
|
|
2529
|
+
const lastIdx = node.liveConsumerNode.length - 1;
|
|
2530
|
+
node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];
|
|
2531
|
+
node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];
|
|
2532
|
+
// Truncate the array.
|
|
2533
|
+
node.liveConsumerNode.length--;
|
|
2534
|
+
node.liveConsumerIndexOfThis.length--;
|
|
2535
|
+
// If the index is still valid, then we need to fix the index pointer from the producer to this
|
|
2536
|
+
// consumer, and update it from `lastIdx` to `idx` (accounting for the move above).
|
|
2537
|
+
if (idx < node.liveConsumerNode.length) {
|
|
2538
|
+
const idxProducer = node.liveConsumerIndexOfThis[idx];
|
|
2539
|
+
const consumer = node.liveConsumerNode[idx];
|
|
2540
|
+
assertConsumerNode(consumer);
|
|
2541
|
+
consumer.producerIndexOfThis[idxProducer] = idx;
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
function consumerIsLive(node) {
|
|
2545
|
+
return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;
|
|
2546
|
+
}
|
|
2547
|
+
function assertConsumerNode(node) {
|
|
2548
|
+
node.producerNode ??= [];
|
|
2549
|
+
node.producerIndexOfThis ??= [];
|
|
2550
|
+
node.producerLastReadVersion ??= [];
|
|
2551
|
+
}
|
|
2552
|
+
function assertProducerNode(node) {
|
|
2553
|
+
node.liveConsumerNode ??= [];
|
|
2554
|
+
node.liveConsumerIndexOfThis ??= [];
|
|
2515
2555
|
}
|
|
2516
2556
|
|
|
2517
2557
|
/**
|
|
@@ -2520,10 +2560,21 @@ class ReactiveNode {
|
|
|
2520
2560
|
* @developerPreview
|
|
2521
2561
|
*/
|
|
2522
2562
|
function computed(computation, options) {
|
|
2523
|
-
const node =
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2563
|
+
const node = Object.create(COMPUTED_NODE);
|
|
2564
|
+
node.computation = computation;
|
|
2565
|
+
options?.equal && (node.equal = options.equal);
|
|
2566
|
+
const computed = () => {
|
|
2567
|
+
// Check if the value needs updating before returning it.
|
|
2568
|
+
producerUpdateValueVersion(node);
|
|
2569
|
+
// Record that someone looked at this signal.
|
|
2570
|
+
producerAccessed(node);
|
|
2571
|
+
if (node.value === ERRORED) {
|
|
2572
|
+
throw node.error;
|
|
2573
|
+
}
|
|
2574
|
+
return node.value;
|
|
2575
|
+
};
|
|
2576
|
+
computed[SIGNAL] = node;
|
|
2577
|
+
return computed;
|
|
2527
2578
|
}
|
|
2528
2579
|
/**
|
|
2529
2580
|
* A dedicated symbol used before a computed value has been calculated for the first time.
|
|
@@ -2542,108 +2593,47 @@ const COMPUTING = Symbol('COMPUTING');
|
|
|
2542
2593
|
* Explicitly typed as `any` so we can use it as signal's value.
|
|
2543
2594
|
*/
|
|
2544
2595
|
const ERRORED = Symbol('ERRORED');
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
* This can also be one of the special values `UNSET`, `COMPUTING`, or `ERRORED`.
|
|
2559
|
-
*/
|
|
2560
|
-
this.value = UNSET;
|
|
2561
|
-
/**
|
|
2562
|
-
* If `value` is `ERRORED`, the error caught from the last computation attempt which will
|
|
2563
|
-
* be re-thrown.
|
|
2564
|
-
*/
|
|
2565
|
-
this.error = null;
|
|
2566
|
-
/**
|
|
2567
|
-
* Flag indicating that the computation is currently stale, meaning that one of the
|
|
2568
|
-
* dependencies has notified of a potential change.
|
|
2569
|
-
*
|
|
2570
|
-
* It's possible that no dependency has _actually_ changed, in which case the `stale`
|
|
2571
|
-
* state can be resolved without recomputing the value.
|
|
2572
|
-
*/
|
|
2573
|
-
this.stale = true;
|
|
2574
|
-
this.consumerAllowSignalWrites = false;
|
|
2575
|
-
}
|
|
2576
|
-
onConsumerDependencyMayHaveChanged() {
|
|
2577
|
-
if (this.stale) {
|
|
2578
|
-
// We've already notified consumers that this value has potentially changed.
|
|
2579
|
-
return;
|
|
2580
|
-
}
|
|
2581
|
-
// Record that the currently cached value may be stale.
|
|
2582
|
-
this.stale = true;
|
|
2583
|
-
// Notify any consumers about the potential change.
|
|
2584
|
-
this.producerMayHaveChanged();
|
|
2585
|
-
}
|
|
2586
|
-
onProducerUpdateValueVersion() {
|
|
2587
|
-
if (!this.stale) {
|
|
2588
|
-
// The current value and its version are already up to date.
|
|
2589
|
-
return;
|
|
2590
|
-
}
|
|
2591
|
-
// The current value is stale. Check whether we need to produce a new one.
|
|
2592
|
-
if (this.value !== UNSET && this.value !== COMPUTING &&
|
|
2593
|
-
!this.consumerPollProducersForChange()) {
|
|
2594
|
-
// Even though we were previously notified of a potential dependency update, all of
|
|
2595
|
-
// our dependencies report that they have not actually changed in value, so we can
|
|
2596
|
-
// resolve the stale state without needing to recompute the current value.
|
|
2597
|
-
this.stale = false;
|
|
2598
|
-
return;
|
|
2599
|
-
}
|
|
2600
|
-
// The current value is stale, and needs to be recomputed. It still may not change -
|
|
2601
|
-
// that depends on whether the newly computed value is equal to the old.
|
|
2602
|
-
this.recomputeValue();
|
|
2603
|
-
}
|
|
2604
|
-
recomputeValue() {
|
|
2605
|
-
if (this.value === COMPUTING) {
|
|
2596
|
+
const COMPUTED_NODE = {
|
|
2597
|
+
...REACTIVE_NODE,
|
|
2598
|
+
value: UNSET,
|
|
2599
|
+
dirty: true,
|
|
2600
|
+
error: null,
|
|
2601
|
+
equal: defaultEquals,
|
|
2602
|
+
producerMustRecompute(node) {
|
|
2603
|
+
// Force a recomputation if there's no current value, or if the current value is in the process
|
|
2604
|
+
// of being calculated (which should throw an error).
|
|
2605
|
+
return node.value === UNSET || node.value === COMPUTING;
|
|
2606
|
+
},
|
|
2607
|
+
producerRecomputeValue(node) {
|
|
2608
|
+
if (node.value === COMPUTING) {
|
|
2606
2609
|
// Our computation somehow led to a cyclic read of itself.
|
|
2607
2610
|
throw new Error('Detected cycle in computations.');
|
|
2608
2611
|
}
|
|
2609
|
-
const oldValue =
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
this.trackingVersion++;
|
|
2613
|
-
const prevConsumer = setActiveConsumer(this);
|
|
2612
|
+
const oldValue = node.value;
|
|
2613
|
+
node.value = COMPUTING;
|
|
2614
|
+
const prevConsumer = consumerBeforeComputation(node);
|
|
2614
2615
|
let newValue;
|
|
2615
2616
|
try {
|
|
2616
|
-
newValue =
|
|
2617
|
+
newValue = node.computation();
|
|
2617
2618
|
}
|
|
2618
2619
|
catch (err) {
|
|
2619
2620
|
newValue = ERRORED;
|
|
2620
|
-
|
|
2621
|
+
node.error = err;
|
|
2621
2622
|
}
|
|
2622
2623
|
finally {
|
|
2623
|
-
|
|
2624
|
+
consumerAfterComputation(node, prevConsumer);
|
|
2624
2625
|
}
|
|
2625
|
-
this.stale = false;
|
|
2626
2626
|
if (oldValue !== UNSET && oldValue !== ERRORED && newValue !== ERRORED &&
|
|
2627
|
-
|
|
2627
|
+
node.equal(oldValue, newValue)) {
|
|
2628
2628
|
// No change to `valueVersion` - old and new values are
|
|
2629
2629
|
// semantically equivalent.
|
|
2630
|
-
|
|
2630
|
+
node.value = oldValue;
|
|
2631
2631
|
return;
|
|
2632
2632
|
}
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
|
-
// Check if the value needs updating before returning it.
|
|
2638
|
-
this.onProducerUpdateValueVersion();
|
|
2639
|
-
// Record that someone looked at this signal.
|
|
2640
|
-
this.producerAccessed();
|
|
2641
|
-
if (this.value === ERRORED) {
|
|
2642
|
-
throw this.error;
|
|
2643
|
-
}
|
|
2644
|
-
return this.value;
|
|
2645
|
-
}
|
|
2646
|
-
}
|
|
2633
|
+
node.value = newValue;
|
|
2634
|
+
node.version++;
|
|
2635
|
+
},
|
|
2636
|
+
};
|
|
2647
2637
|
|
|
2648
2638
|
function defaultThrowError() {
|
|
2649
2639
|
throw new Error();
|
|
@@ -2663,88 +2653,24 @@ function setThrowInvalidWriteToSignalError(fn) {
|
|
|
2663
2653
|
* of setting a signal.
|
|
2664
2654
|
*/
|
|
2665
2655
|
let postSignalSetFn = null;
|
|
2666
|
-
class WritableSignalImpl extends ReactiveNode {
|
|
2667
|
-
constructor(value, equal) {
|
|
2668
|
-
super();
|
|
2669
|
-
this.value = value;
|
|
2670
|
-
this.equal = equal;
|
|
2671
|
-
this.consumerAllowSignalWrites = false;
|
|
2672
|
-
}
|
|
2673
|
-
onConsumerDependencyMayHaveChanged() {
|
|
2674
|
-
// This never happens for writable signals as they're not consumers.
|
|
2675
|
-
}
|
|
2676
|
-
onProducerUpdateValueVersion() {
|
|
2677
|
-
// Writable signal value versions are always up to date.
|
|
2678
|
-
}
|
|
2679
|
-
/**
|
|
2680
|
-
* Directly update the value of the signal to a new value, which may or may not be
|
|
2681
|
-
* equal to the previous.
|
|
2682
|
-
*
|
|
2683
|
-
* In the event that `newValue` is semantically equal to the current value, `set` is
|
|
2684
|
-
* a no-op.
|
|
2685
|
-
*/
|
|
2686
|
-
set(newValue) {
|
|
2687
|
-
if (!this.producerUpdatesAllowed) {
|
|
2688
|
-
throwInvalidWriteToSignalError();
|
|
2689
|
-
}
|
|
2690
|
-
if (!this.equal(this.value, newValue)) {
|
|
2691
|
-
this.value = newValue;
|
|
2692
|
-
this.valueVersion++;
|
|
2693
|
-
this.producerMayHaveChanged();
|
|
2694
|
-
postSignalSetFn?.();
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
/**
|
|
2698
|
-
* Derive a new value for the signal from its current value using the `updater` function.
|
|
2699
|
-
*
|
|
2700
|
-
* This is equivalent to calling `set` on the result of running `updater` on the current
|
|
2701
|
-
* value.
|
|
2702
|
-
*/
|
|
2703
|
-
update(updater) {
|
|
2704
|
-
if (!this.producerUpdatesAllowed) {
|
|
2705
|
-
throwInvalidWriteToSignalError();
|
|
2706
|
-
}
|
|
2707
|
-
this.set(updater(this.value));
|
|
2708
|
-
}
|
|
2709
|
-
/**
|
|
2710
|
-
* Calls `mutator` on the current value and assumes that it has been mutated.
|
|
2711
|
-
*/
|
|
2712
|
-
mutate(mutator) {
|
|
2713
|
-
if (!this.producerUpdatesAllowed) {
|
|
2714
|
-
throwInvalidWriteToSignalError();
|
|
2715
|
-
}
|
|
2716
|
-
// Mutate bypasses equality checks as it's by definition changing the value.
|
|
2717
|
-
mutator(this.value);
|
|
2718
|
-
this.valueVersion++;
|
|
2719
|
-
this.producerMayHaveChanged();
|
|
2720
|
-
postSignalSetFn?.();
|
|
2721
|
-
}
|
|
2722
|
-
asReadonly() {
|
|
2723
|
-
if (this.readonlySignal === undefined) {
|
|
2724
|
-
this.readonlySignal = createSignalFromFunction(this, () => this.signal());
|
|
2725
|
-
}
|
|
2726
|
-
return this.readonlySignal;
|
|
2727
|
-
}
|
|
2728
|
-
signal() {
|
|
2729
|
-
this.producerAccessed();
|
|
2730
|
-
return this.value;
|
|
2731
|
-
}
|
|
2732
|
-
}
|
|
2733
2656
|
/**
|
|
2734
2657
|
* Create a `Signal` that can be set or updated directly.
|
|
2735
2658
|
*
|
|
2736
2659
|
* @developerPreview
|
|
2737
2660
|
*/
|
|
2738
2661
|
function signal(initialValue, options) {
|
|
2739
|
-
const
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2662
|
+
const node = Object.create(SIGNAL_NODE);
|
|
2663
|
+
node.value = initialValue;
|
|
2664
|
+
options?.equal && (node.equal = options.equal);
|
|
2665
|
+
function signalFn() {
|
|
2666
|
+
producerAccessed(node);
|
|
2667
|
+
return node.value;
|
|
2668
|
+
}
|
|
2669
|
+
signalFn.set = signalSetFn;
|
|
2670
|
+
signalFn.update = signalUpdateFn;
|
|
2671
|
+
signalFn.mutate = signalMutateFn;
|
|
2672
|
+
signalFn.asReadonly = signalAsReadonlyFn;
|
|
2673
|
+
signalFn[SIGNAL] = node;
|
|
2748
2674
|
return signalFn;
|
|
2749
2675
|
}
|
|
2750
2676
|
function setPostSignalSetFn(fn) {
|
|
@@ -2752,6 +2678,50 @@ function setPostSignalSetFn(fn) {
|
|
|
2752
2678
|
postSignalSetFn = fn;
|
|
2753
2679
|
return prev;
|
|
2754
2680
|
}
|
|
2681
|
+
const SIGNAL_NODE = {
|
|
2682
|
+
...REACTIVE_NODE,
|
|
2683
|
+
equal: defaultEquals,
|
|
2684
|
+
readonlyFn: undefined,
|
|
2685
|
+
};
|
|
2686
|
+
function signalValueChanged(node) {
|
|
2687
|
+
node.version++;
|
|
2688
|
+
producerNotifyConsumers(node);
|
|
2689
|
+
postSignalSetFn?.();
|
|
2690
|
+
}
|
|
2691
|
+
function signalSetFn(newValue) {
|
|
2692
|
+
const node = this[SIGNAL];
|
|
2693
|
+
if (!producerUpdatesAllowed()) {
|
|
2694
|
+
throwInvalidWriteToSignalError();
|
|
2695
|
+
}
|
|
2696
|
+
if (!node.equal(node.value, newValue)) {
|
|
2697
|
+
node.value = newValue;
|
|
2698
|
+
signalValueChanged(node);
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
function signalUpdateFn(updater) {
|
|
2702
|
+
if (!producerUpdatesAllowed()) {
|
|
2703
|
+
throwInvalidWriteToSignalError();
|
|
2704
|
+
}
|
|
2705
|
+
signalSetFn.call(this, updater(this[SIGNAL].value));
|
|
2706
|
+
}
|
|
2707
|
+
function signalMutateFn(mutator) {
|
|
2708
|
+
const node = this[SIGNAL];
|
|
2709
|
+
if (!producerUpdatesAllowed()) {
|
|
2710
|
+
throwInvalidWriteToSignalError();
|
|
2711
|
+
}
|
|
2712
|
+
// Mutate bypasses equality checks as it's by definition changing the value.
|
|
2713
|
+
mutator(node.value);
|
|
2714
|
+
signalValueChanged(node);
|
|
2715
|
+
}
|
|
2716
|
+
function signalAsReadonlyFn() {
|
|
2717
|
+
const node = this[SIGNAL];
|
|
2718
|
+
if (node.readonlyFn === undefined) {
|
|
2719
|
+
const readonlyFn = () => this();
|
|
2720
|
+
readonlyFn[SIGNAL] = node;
|
|
2721
|
+
node.readonlyFn = readonlyFn;
|
|
2722
|
+
}
|
|
2723
|
+
return node.readonlyFn;
|
|
2724
|
+
}
|
|
2755
2725
|
|
|
2756
2726
|
/**
|
|
2757
2727
|
* Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function
|
|
@@ -2771,63 +2741,53 @@ function untracked(nonReactiveReadsFn) {
|
|
|
2771
2741
|
}
|
|
2772
2742
|
}
|
|
2773
2743
|
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
*
|
|
2779
|
-
* `Watch` doesn't run reactive expressions itself, but relies on a consumer-
|
|
2780
|
-
* provided scheduling operation to coordinate calling `Watch.run()`.
|
|
2781
|
-
*/
|
|
2782
|
-
class Watch extends ReactiveNode {
|
|
2783
|
-
constructor(watch, schedule, allowSignalWrites) {
|
|
2784
|
-
super();
|
|
2785
|
-
this.watch = watch;
|
|
2786
|
-
this.schedule = schedule;
|
|
2787
|
-
this.dirty = false;
|
|
2788
|
-
this.cleanupFn = NOOP_CLEANUP_FN;
|
|
2789
|
-
this.registerOnCleanup = (cleanupFn) => {
|
|
2790
|
-
this.cleanupFn = cleanupFn;
|
|
2791
|
-
};
|
|
2792
|
-
this.consumerAllowSignalWrites = allowSignalWrites;
|
|
2793
|
-
}
|
|
2794
|
-
notify() {
|
|
2795
|
-
if (!this.dirty) {
|
|
2796
|
-
this.schedule(this);
|
|
2797
|
-
}
|
|
2798
|
-
this.dirty = true;
|
|
2799
|
-
}
|
|
2800
|
-
onConsumerDependencyMayHaveChanged() {
|
|
2801
|
-
this.notify();
|
|
2744
|
+
function watch(fn, schedule, allowSignalWrites) {
|
|
2745
|
+
const node = Object.create(WATCH_NODE);
|
|
2746
|
+
if (allowSignalWrites) {
|
|
2747
|
+
node.consumerAllowSignalWrites = true;
|
|
2802
2748
|
}
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
*/
|
|
2812
|
-
run() {
|
|
2813
|
-
this.dirty = false;
|
|
2814
|
-
if (this.trackingVersion !== 0 && !this.consumerPollProducersForChange()) {
|
|
2749
|
+
node.fn = fn;
|
|
2750
|
+
node.schedule = schedule;
|
|
2751
|
+
const registerOnCleanup = (cleanupFn) => {
|
|
2752
|
+
node.cleanupFn = cleanupFn;
|
|
2753
|
+
};
|
|
2754
|
+
const run = () => {
|
|
2755
|
+
node.dirty = false;
|
|
2756
|
+
if (node.hasRun && !consumerPollProducersForChange(node)) {
|
|
2815
2757
|
return;
|
|
2816
2758
|
}
|
|
2817
|
-
|
|
2818
|
-
|
|
2759
|
+
node.hasRun = true;
|
|
2760
|
+
const prevConsumer = consumerBeforeComputation(node);
|
|
2819
2761
|
try {
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2762
|
+
node.cleanupFn();
|
|
2763
|
+
node.cleanupFn = NOOP_CLEANUP_FN;
|
|
2764
|
+
node.fn(registerOnCleanup);
|
|
2823
2765
|
}
|
|
2824
2766
|
finally {
|
|
2825
|
-
|
|
2767
|
+
consumerAfterComputation(node, prevConsumer);
|
|
2826
2768
|
}
|
|
2827
|
-
}
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2769
|
+
};
|
|
2770
|
+
node.ref = {
|
|
2771
|
+
notify: () => consumerMarkDirty(node),
|
|
2772
|
+
run,
|
|
2773
|
+
cleanup: () => node.cleanupFn(),
|
|
2774
|
+
};
|
|
2775
|
+
return node.ref;
|
|
2776
|
+
}
|
|
2777
|
+
const NOOP_CLEANUP_FN = () => { };
|
|
2778
|
+
const WATCH_NODE = {
|
|
2779
|
+
...REACTIVE_NODE,
|
|
2780
|
+
consumerIsAlwaysLive: true,
|
|
2781
|
+
consumerAllowSignalWrites: false,
|
|
2782
|
+
consumerMarkedDirty: (node) => {
|
|
2783
|
+
node.schedule(node.ref);
|
|
2784
|
+
},
|
|
2785
|
+
hasRun: false,
|
|
2786
|
+
cleanupFn: NOOP_CLEANUP_FN,
|
|
2787
|
+
};
|
|
2788
|
+
|
|
2789
|
+
function setAlternateWeakRefImpl(impl) {
|
|
2790
|
+
// TODO: remove this function
|
|
2831
2791
|
}
|
|
2832
2792
|
|
|
2833
2793
|
/**
|
|
@@ -4081,6 +4041,21 @@ function toTNodeTypeAsString(tNodeType) {
|
|
|
4081
4041
|
(tNodeType & 64 /* TNodeType.Placeholder */) && (text += '|Placeholder');
|
|
4082
4042
|
return text.length > 0 ? text.substring(1) : text;
|
|
4083
4043
|
}
|
|
4044
|
+
/**
|
|
4045
|
+
* Helper function to detect if a given value matches a `TNode` shape.
|
|
4046
|
+
*
|
|
4047
|
+
* The logic uses the `insertBeforeIndex` and its possible values as
|
|
4048
|
+
* a way to differentiate a TNode shape from other types of objects
|
|
4049
|
+
* within the `TView.data`. This is not a perfect check, but it can
|
|
4050
|
+
* be a reasonable differentiator, since we control the shapes of objects
|
|
4051
|
+
* within `TView.data`.
|
|
4052
|
+
*/
|
|
4053
|
+
function isTNodeShape(value) {
|
|
4054
|
+
return value != null && typeof value === 'object' &&
|
|
4055
|
+
(value.insertBeforeIndex === null ||
|
|
4056
|
+
typeof value.insertBeforeIndex === 'number' ||
|
|
4057
|
+
Array.isArray(value.insertBeforeIndex));
|
|
4058
|
+
}
|
|
4084
4059
|
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
|
4085
4060
|
// failure based on types.
|
|
4086
4061
|
const unusedValueExportToPlacateAjd$1 = 1;
|
|
@@ -8696,8 +8671,8 @@ function detachView(lContainer, removeIndex) {
|
|
|
8696
8671
|
function destroyLView(tView, lView) {
|
|
8697
8672
|
if (!(lView[FLAGS] & 256 /* LViewFlags.Destroyed */)) {
|
|
8698
8673
|
const renderer = lView[RENDERER];
|
|
8699
|
-
lView[REACTIVE_TEMPLATE_CONSUMER]
|
|
8700
|
-
lView[REACTIVE_HOST_BINDING_CONSUMER]
|
|
8674
|
+
lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy(lView[REACTIVE_TEMPLATE_CONSUMER]);
|
|
8675
|
+
lView[REACTIVE_HOST_BINDING_CONSUMER] && consumerDestroy(lView[REACTIVE_HOST_BINDING_CONSUMER]);
|
|
8701
8676
|
if (renderer.destroyNode) {
|
|
8702
8677
|
applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
|
|
8703
8678
|
}
|
|
@@ -10859,7 +10834,7 @@ class Version {
|
|
|
10859
10834
|
/**
|
|
10860
10835
|
* @publicApi
|
|
10861
10836
|
*/
|
|
10862
|
-
const VERSION = new Version('17.0.0-next.
|
|
10837
|
+
const VERSION = new Version('17.0.0-next.3');
|
|
10863
10838
|
|
|
10864
10839
|
// This default value is when checking the hierarchy for a token.
|
|
10865
10840
|
//
|
|
@@ -11316,6 +11291,9 @@ function forkInnerZoneWithAngularBehavior(zone) {
|
|
|
11316
11291
|
name: 'angular',
|
|
11317
11292
|
properties: { 'isAngularZone': true },
|
|
11318
11293
|
onInvokeTask: (delegate, current, target, task, applyThis, applyArgs) => {
|
|
11294
|
+
if (shouldBeIgnoredByZone(applyArgs)) {
|
|
11295
|
+
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
|
11296
|
+
}
|
|
11319
11297
|
try {
|
|
11320
11298
|
onEnter(zone);
|
|
11321
11299
|
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
|
@@ -11467,6 +11445,18 @@ function isStableFactory() {
|
|
|
11467
11445
|
});
|
|
11468
11446
|
return merge$1(isCurrentlyStable, isStable.pipe(share()));
|
|
11469
11447
|
}
|
|
11448
|
+
function shouldBeIgnoredByZone(applyArgs) {
|
|
11449
|
+
if (!Array.isArray(applyArgs)) {
|
|
11450
|
+
return false;
|
|
11451
|
+
}
|
|
11452
|
+
// We should only ever get 1 arg passed through to invokeTask.
|
|
11453
|
+
// Short circuit here incase that behavior changes.
|
|
11454
|
+
if (applyArgs.length !== 1) {
|
|
11455
|
+
return false;
|
|
11456
|
+
}
|
|
11457
|
+
// Prevent triggering change detection when the __ignore_ng_zone__ flag is detected.
|
|
11458
|
+
return applyArgs[0].data?.['__ignore_ng_zone__'] === true;
|
|
11459
|
+
}
|
|
11470
11460
|
|
|
11471
11461
|
// Public API for Zone
|
|
11472
11462
|
|
|
@@ -11520,13 +11510,16 @@ function afterRender(callback, options) {
|
|
|
11520
11510
|
let destroy;
|
|
11521
11511
|
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
|
11522
11512
|
const manager = injector.get(AfterRenderEventManager);
|
|
11513
|
+
// Lazily initialize the handler implementation, if necessary. This is so that it can be
|
|
11514
|
+
// tree-shaken if `afterRender` and `afterNextRender` aren't used.
|
|
11515
|
+
const handler = manager.handler ??= new AfterRenderCallbackHandlerImpl();
|
|
11523
11516
|
const ngZone = injector.get(NgZone);
|
|
11524
11517
|
const instance = new AfterRenderCallback(() => ngZone.runOutsideAngular(callback));
|
|
11525
11518
|
destroy = () => {
|
|
11526
|
-
|
|
11519
|
+
handler.unregister(instance);
|
|
11527
11520
|
unregisterFn();
|
|
11528
11521
|
};
|
|
11529
|
-
|
|
11522
|
+
handler.register(instance);
|
|
11530
11523
|
return { destroy };
|
|
11531
11524
|
}
|
|
11532
11525
|
/**
|
|
@@ -11580,21 +11573,23 @@ function afterNextRender(callback, options) {
|
|
|
11580
11573
|
let destroy;
|
|
11581
11574
|
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
|
11582
11575
|
const manager = injector.get(AfterRenderEventManager);
|
|
11576
|
+
// Lazily initialize the handler implementation, if necessary. This is so that it can be
|
|
11577
|
+
// tree-shaken if `afterRender` and `afterNextRender` aren't used.
|
|
11578
|
+
const handler = manager.handler ??= new AfterRenderCallbackHandlerImpl();
|
|
11583
11579
|
const ngZone = injector.get(NgZone);
|
|
11584
11580
|
const instance = new AfterRenderCallback(() => {
|
|
11585
11581
|
destroy?.();
|
|
11586
11582
|
ngZone.runOutsideAngular(callback);
|
|
11587
11583
|
});
|
|
11588
11584
|
destroy = () => {
|
|
11589
|
-
|
|
11585
|
+
handler.unregister(instance);
|
|
11590
11586
|
unregisterFn();
|
|
11591
11587
|
};
|
|
11592
|
-
|
|
11588
|
+
handler.register(instance);
|
|
11593
11589
|
return { destroy };
|
|
11594
11590
|
}
|
|
11595
11591
|
/**
|
|
11596
11592
|
* A wrapper around a function to be used as an after render callback.
|
|
11597
|
-
* @private
|
|
11598
11593
|
*/
|
|
11599
11594
|
class AfterRenderCallback {
|
|
11600
11595
|
constructor(callback) {
|
|
@@ -11605,65 +11600,87 @@ class AfterRenderCallback {
|
|
|
11605
11600
|
}
|
|
11606
11601
|
}
|
|
11607
11602
|
/**
|
|
11608
|
-
*
|
|
11603
|
+
* Core functionality for `afterRender` and `afterNextRender`. Kept separate from
|
|
11604
|
+
* `AfterRenderEventManager` for tree-shaking.
|
|
11609
11605
|
*/
|
|
11610
|
-
class
|
|
11606
|
+
class AfterRenderCallbackHandlerImpl {
|
|
11611
11607
|
constructor() {
|
|
11608
|
+
this.executingCallbacks = false;
|
|
11612
11609
|
this.callbacks = new Set();
|
|
11613
11610
|
this.deferredCallbacks = new Set();
|
|
11614
|
-
this.renderDepth = 0;
|
|
11615
|
-
this.runningCallbacks = false;
|
|
11616
11611
|
}
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
* Throws if called from an `afterRender` callback.
|
|
11620
|
-
*/
|
|
11621
|
-
begin() {
|
|
11622
|
-
if (this.runningCallbacks) {
|
|
11612
|
+
validateBegin() {
|
|
11613
|
+
if (this.executingCallbacks) {
|
|
11623
11614
|
throw new RuntimeError(102 /* RuntimeErrorCode.RECURSIVE_APPLICATION_RENDER */, ngDevMode &&
|
|
11624
11615
|
'A new render operation began before the previous operation ended. ' +
|
|
11625
11616
|
'Did you trigger change detection from afterRender or afterNextRender?');
|
|
11626
11617
|
}
|
|
11627
|
-
this.renderDepth++;
|
|
11628
|
-
}
|
|
11629
|
-
/**
|
|
11630
|
-
* Mark the end of a render operation. Registered callbacks
|
|
11631
|
-
* are invoked if there are no more pending operations.
|
|
11632
|
-
*/
|
|
11633
|
-
end() {
|
|
11634
|
-
this.renderDepth--;
|
|
11635
|
-
if (this.renderDepth === 0) {
|
|
11636
|
-
try {
|
|
11637
|
-
this.runningCallbacks = true;
|
|
11638
|
-
for (const callback of this.callbacks) {
|
|
11639
|
-
callback.invoke();
|
|
11640
|
-
}
|
|
11641
|
-
}
|
|
11642
|
-
finally {
|
|
11643
|
-
this.runningCallbacks = false;
|
|
11644
|
-
for (const callback of this.deferredCallbacks) {
|
|
11645
|
-
this.callbacks.add(callback);
|
|
11646
|
-
}
|
|
11647
|
-
this.deferredCallbacks.clear();
|
|
11648
|
-
}
|
|
11649
|
-
}
|
|
11650
11618
|
}
|
|
11651
11619
|
register(callback) {
|
|
11652
11620
|
// If we're currently running callbacks, new callbacks should be deferred
|
|
11653
11621
|
// until the next render operation.
|
|
11654
|
-
const target = this.
|
|
11622
|
+
const target = this.executingCallbacks ? this.deferredCallbacks : this.callbacks;
|
|
11655
11623
|
target.add(callback);
|
|
11656
11624
|
}
|
|
11657
11625
|
unregister(callback) {
|
|
11658
11626
|
this.callbacks.delete(callback);
|
|
11659
11627
|
this.deferredCallbacks.delete(callback);
|
|
11660
11628
|
}
|
|
11661
|
-
|
|
11629
|
+
execute() {
|
|
11630
|
+
try {
|
|
11631
|
+
this.executingCallbacks = true;
|
|
11632
|
+
for (const callback of this.callbacks) {
|
|
11633
|
+
callback.invoke();
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
11636
|
+
finally {
|
|
11637
|
+
this.executingCallbacks = false;
|
|
11638
|
+
for (const callback of this.deferredCallbacks) {
|
|
11639
|
+
this.callbacks.add(callback);
|
|
11640
|
+
}
|
|
11641
|
+
this.deferredCallbacks.clear();
|
|
11642
|
+
}
|
|
11643
|
+
}
|
|
11644
|
+
destroy() {
|
|
11662
11645
|
this.callbacks.clear();
|
|
11663
11646
|
this.deferredCallbacks.clear();
|
|
11664
11647
|
}
|
|
11665
|
-
|
|
11666
|
-
|
|
11648
|
+
}
|
|
11649
|
+
/**
|
|
11650
|
+
* Implements core timing for `afterRender` and `afterNextRender` events.
|
|
11651
|
+
* Delegates to an optional `AfterRenderCallbackHandler` for implementation.
|
|
11652
|
+
*/
|
|
11653
|
+
class AfterRenderEventManager {
|
|
11654
|
+
constructor() {
|
|
11655
|
+
this.renderDepth = 0;
|
|
11656
|
+
/* @internal */
|
|
11657
|
+
this.handler = null;
|
|
11658
|
+
}
|
|
11659
|
+
/**
|
|
11660
|
+
* Mark the beginning of a render operation (i.e. CD cycle).
|
|
11661
|
+
* Throws if called while executing callbacks.
|
|
11662
|
+
*/
|
|
11663
|
+
begin() {
|
|
11664
|
+
this.handler?.validateBegin();
|
|
11665
|
+
this.renderDepth++;
|
|
11666
|
+
}
|
|
11667
|
+
/**
|
|
11668
|
+
* Mark the end of a render operation. Callbacks will be
|
|
11669
|
+
* executed if there are no more pending operations.
|
|
11670
|
+
*/
|
|
11671
|
+
end() {
|
|
11672
|
+
ngDevMode && assertGreaterThan(this.renderDepth, 0, 'renderDepth must be greater than 0');
|
|
11673
|
+
this.renderDepth--;
|
|
11674
|
+
if (this.renderDepth === 0) {
|
|
11675
|
+
this.handler?.execute();
|
|
11676
|
+
}
|
|
11677
|
+
}
|
|
11678
|
+
ngOnDestroy() {
|
|
11679
|
+
this.handler?.destroy();
|
|
11680
|
+
this.handler = null;
|
|
11681
|
+
}
|
|
11682
|
+
/** @nocollapse */
|
|
11683
|
+
static { this.ɵprov = ɵɵdefineInjectable({
|
|
11667
11684
|
token: AfterRenderEventManager,
|
|
11668
11685
|
providedIn: 'root',
|
|
11669
11686
|
factory: () => new AfterRenderEventManager(),
|
|
@@ -11897,48 +11914,11 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
|
|
|
11897
11914
|
return { propName: undefined, oldValue, newValue };
|
|
11898
11915
|
}
|
|
11899
11916
|
|
|
11900
|
-
class ReactiveLViewConsumer extends ReactiveNode {
|
|
11901
|
-
constructor() {
|
|
11902
|
-
super(...arguments);
|
|
11903
|
-
this.consumerAllowSignalWrites = false;
|
|
11904
|
-
this._lView = null;
|
|
11905
|
-
}
|
|
11906
|
-
set lView(lView) {
|
|
11907
|
-
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11908
|
-
assertEqual(this._lView, null, 'Consumer already associated with a view.');
|
|
11909
|
-
this._lView = lView;
|
|
11910
|
-
}
|
|
11911
|
-
onConsumerDependencyMayHaveChanged() {
|
|
11912
|
-
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11913
|
-
assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
|
|
11914
|
-
markViewDirty(this._lView);
|
|
11915
|
-
}
|
|
11916
|
-
onProducerUpdateValueVersion() {
|
|
11917
|
-
// This type doesn't implement the producer side of a `ReactiveNode`.
|
|
11918
|
-
}
|
|
11919
|
-
get hasReadASignal() {
|
|
11920
|
-
return this.hasProducers;
|
|
11921
|
-
}
|
|
11922
|
-
runInContext(fn, rf, ctx) {
|
|
11923
|
-
const prevConsumer = setActiveConsumer(this);
|
|
11924
|
-
this.trackingVersion++;
|
|
11925
|
-
try {
|
|
11926
|
-
fn(rf, ctx);
|
|
11927
|
-
}
|
|
11928
|
-
finally {
|
|
11929
|
-
setActiveConsumer(prevConsumer);
|
|
11930
|
-
}
|
|
11931
|
-
}
|
|
11932
|
-
destroy() {
|
|
11933
|
-
// Incrementing the version means that every producer which tries to update this consumer will
|
|
11934
|
-
// consider its record stale, and not notify.
|
|
11935
|
-
this.trackingVersion++;
|
|
11936
|
-
}
|
|
11937
|
-
}
|
|
11938
11917
|
let currentConsumer = null;
|
|
11939
|
-
function
|
|
11940
|
-
|
|
11941
|
-
|
|
11918
|
+
function setLViewForConsumer(node, lView) {
|
|
11919
|
+
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11920
|
+
assertEqual(node.lView, null, 'Consumer already associated with a view.');
|
|
11921
|
+
node.lView = lView;
|
|
11942
11922
|
}
|
|
11943
11923
|
/**
|
|
11944
11924
|
* Create a new template consumer pointing at the specified LView.
|
|
@@ -11960,12 +11940,29 @@ function getReactiveLViewConsumer(lView, slot) {
|
|
|
11960
11940
|
*/
|
|
11961
11941
|
function commitLViewConsumerIfHasProducers(lView, slot) {
|
|
11962
11942
|
const consumer = getOrCreateCurrentLViewConsumer();
|
|
11963
|
-
if (!consumer.
|
|
11943
|
+
if (!consumer.producerNode?.length) {
|
|
11964
11944
|
return;
|
|
11965
11945
|
}
|
|
11966
11946
|
lView[slot] = currentConsumer;
|
|
11967
11947
|
consumer.lView = lView;
|
|
11968
|
-
currentConsumer =
|
|
11948
|
+
currentConsumer = createLViewConsumer();
|
|
11949
|
+
}
|
|
11950
|
+
const REACTIVE_LVIEW_CONSUMER_NODE = {
|
|
11951
|
+
...REACTIVE_NODE,
|
|
11952
|
+
consumerIsAlwaysLive: true,
|
|
11953
|
+
consumerMarkedDirty: (node) => {
|
|
11954
|
+
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11955
|
+
assertDefined(node.lView, 'Updating a signal during template or host binding execution is not allowed.');
|
|
11956
|
+
markViewDirty(node.lView);
|
|
11957
|
+
},
|
|
11958
|
+
lView: null,
|
|
11959
|
+
};
|
|
11960
|
+
function createLViewConsumer() {
|
|
11961
|
+
return Object.create(REACTIVE_LVIEW_CONSUMER_NODE);
|
|
11962
|
+
}
|
|
11963
|
+
function getOrCreateCurrentLViewConsumer() {
|
|
11964
|
+
currentConsumer ??= createLViewConsumer();
|
|
11965
|
+
return currentConsumer;
|
|
11969
11966
|
}
|
|
11970
11967
|
|
|
11971
11968
|
/** A special value which designates that a value has not changed. */
|
|
@@ -12082,8 +12079,15 @@ function processHostBindingOpCodes(tView, lView) {
|
|
|
12082
12079
|
const bindingRootIndx = hostBindingOpCodes[++i];
|
|
12083
12080
|
const hostBindingFn = hostBindingOpCodes[++i];
|
|
12084
12081
|
setBindingRootForHostBindings(bindingRootIndx, directiveIdx);
|
|
12085
|
-
|
|
12086
|
-
|
|
12082
|
+
consumer.dirty = false;
|
|
12083
|
+
const prevConsumer = consumerBeforeComputation(consumer);
|
|
12084
|
+
try {
|
|
12085
|
+
const context = lView[directiveIdx];
|
|
12086
|
+
hostBindingFn(2 /* RenderFlags.Update */, context);
|
|
12087
|
+
}
|
|
12088
|
+
finally {
|
|
12089
|
+
consumerAfterComputation(consumer, prevConsumer);
|
|
12090
|
+
}
|
|
12087
12091
|
}
|
|
12088
12092
|
}
|
|
12089
12093
|
}
|
|
@@ -12223,17 +12227,16 @@ function executeTemplate(tView, lView, templateFn, rf, context) {
|
|
|
12223
12227
|
}
|
|
12224
12228
|
const preHookType = isUpdatePhase ? 2 /* ProfilerEvent.TemplateUpdateStart */ : 0 /* ProfilerEvent.TemplateCreateStart */;
|
|
12225
12229
|
profiler(preHookType, context);
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
try {
|
|
12232
|
-
templateFn(rf, context);
|
|
12233
|
-
}
|
|
12234
|
-
finally {
|
|
12235
|
-
setActiveConsumer(prevConsumer);
|
|
12230
|
+
const effectiveConsumer = isUpdatePhase ? consumer : null;
|
|
12231
|
+
const prevConsumer = consumerBeforeComputation(effectiveConsumer);
|
|
12232
|
+
try {
|
|
12233
|
+
if (effectiveConsumer !== null) {
|
|
12234
|
+
effectiveConsumer.dirty = false;
|
|
12236
12235
|
}
|
|
12236
|
+
templateFn(rf, context);
|
|
12237
|
+
}
|
|
12238
|
+
finally {
|
|
12239
|
+
consumerAfterComputation(effectiveConsumer, prevConsumer);
|
|
12237
12240
|
}
|
|
12238
12241
|
}
|
|
12239
12242
|
finally {
|
|
@@ -13487,21 +13490,21 @@ class EffectManager {
|
|
|
13487
13490
|
}
|
|
13488
13491
|
create(effectFn, destroyRef, allowSignalWrites) {
|
|
13489
13492
|
const zone = (typeof Zone === 'undefined') ? null : Zone.current;
|
|
13490
|
-
const
|
|
13493
|
+
const w = watch(effectFn, (watch) => {
|
|
13491
13494
|
if (!this.all.has(watch)) {
|
|
13492
13495
|
return;
|
|
13493
13496
|
}
|
|
13494
13497
|
this.queue.set(watch, zone);
|
|
13495
13498
|
}, allowSignalWrites);
|
|
13496
|
-
this.all.add(
|
|
13499
|
+
this.all.add(w);
|
|
13497
13500
|
// Effects start dirty.
|
|
13498
|
-
|
|
13501
|
+
w.notify();
|
|
13499
13502
|
let unregisterOnDestroy;
|
|
13500
13503
|
const destroy = () => {
|
|
13501
|
-
|
|
13504
|
+
w.cleanup();
|
|
13502
13505
|
unregisterOnDestroy?.();
|
|
13503
|
-
this.all.delete(
|
|
13504
|
-
this.queue.delete(
|
|
13506
|
+
this.all.delete(w);
|
|
13507
|
+
this.queue.delete(w);
|
|
13505
13508
|
};
|
|
13506
13509
|
unregisterOnDestroy = destroyRef?.onDestroy(destroy);
|
|
13507
13510
|
return {
|
|
@@ -13749,7 +13752,7 @@ function refreshView(tView, lView, templateFn, context) {
|
|
|
13749
13752
|
// insertion points. This is needed to avoid the situation where the template is defined in this
|
|
13750
13753
|
// `LView` but its declaration appears after the insertion component.
|
|
13751
13754
|
markTransplantedViewsForRefresh(lView);
|
|
13752
|
-
detectChangesInEmbeddedViews(lView,
|
|
13755
|
+
detectChangesInEmbeddedViews(lView, 0 /* ChangeDetectionMode.Global */);
|
|
13753
13756
|
// Content query results must be refreshed before content hooks are called.
|
|
13754
13757
|
if (tView.contentQueries !== null) {
|
|
13755
13758
|
refreshContentQueries(tView, lView);
|
|
@@ -13885,15 +13888,14 @@ function detectChangesInView(lView, mode) {
|
|
|
13885
13888
|
return;
|
|
13886
13889
|
}
|
|
13887
13890
|
const tView = lView[TVIEW];
|
|
13888
|
-
|
|
13891
|
+
const flags = lView[FLAGS];
|
|
13892
|
+
if ((flags & (16 /* LViewFlags.CheckAlways */ | 64 /* LViewFlags.Dirty */) &&
|
|
13889
13893
|
mode === 0 /* ChangeDetectionMode.Global */) ||
|
|
13890
|
-
|
|
13891
|
-
mode === 2 /* ChangeDetectionMode.BugToForceRefreshAndIgnoreViewFlags */) {
|
|
13894
|
+
flags & 1024 /* LViewFlags.RefreshView */) {
|
|
13892
13895
|
refreshView(tView, lView, tView.template, lView[CONTEXT]);
|
|
13893
13896
|
}
|
|
13894
13897
|
else if (lView[DESCENDANT_VIEWS_TO_REFRESH] > 0) {
|
|
13895
13898
|
detectChangesInEmbeddedViews(lView, 1 /* ChangeDetectionMode.Targeted */);
|
|
13896
|
-
const tView = lView[TVIEW];
|
|
13897
13899
|
const components = tView.components;
|
|
13898
13900
|
if (components !== null) {
|
|
13899
13901
|
detectChangesInChildComponents(lView, components, 1 /* ChangeDetectionMode.Targeted */);
|
|
@@ -15653,14 +15655,12 @@ function getTStylingRangePrev(tStylingRange) {
|
|
|
15653
15655
|
}
|
|
15654
15656
|
function getTStylingRangePrevDuplicate(tStylingRange) {
|
|
15655
15657
|
ngDevMode && assertNumber(tStylingRange, 'expected number');
|
|
15656
|
-
return (tStylingRange & 2 /* StylingRange.PREV_DUPLICATE */) ==
|
|
15657
|
-
2 /* StylingRange.PREV_DUPLICATE */;
|
|
15658
|
+
return (tStylingRange & 2 /* StylingRange.PREV_DUPLICATE */) == 2 /* StylingRange.PREV_DUPLICATE */;
|
|
15658
15659
|
}
|
|
15659
15660
|
function setTStylingRangePrev(tStylingRange, previous) {
|
|
15660
15661
|
ngDevMode && assertNumber(tStylingRange, 'expected number');
|
|
15661
15662
|
ngDevMode && assertNumberInRange(previous, 0, 32767 /* StylingRange.UNSIGNED_MASK */);
|
|
15662
|
-
return ((tStylingRange & ~4294836224 /* StylingRange.PREV_MASK */) |
|
|
15663
|
-
(previous << 17 /* StylingRange.PREV_SHIFT */));
|
|
15663
|
+
return ((tStylingRange & ~4294836224 /* StylingRange.PREV_MASK */) | (previous << 17 /* StylingRange.PREV_SHIFT */));
|
|
15664
15664
|
}
|
|
15665
15665
|
function setTStylingRangePrevDuplicate(tStylingRange) {
|
|
15666
15666
|
ngDevMode && assertNumber(tStylingRange, 'expected number');
|
|
@@ -15678,8 +15678,7 @@ function setTStylingRangeNext(tStylingRange, next) {
|
|
|
15678
15678
|
}
|
|
15679
15679
|
function getTStylingRangeNextDuplicate(tStylingRange) {
|
|
15680
15680
|
ngDevMode && assertNumber(tStylingRange, 'expected number');
|
|
15681
|
-
return (tStylingRange & 1 /* StylingRange.NEXT_DUPLICATE */) ===
|
|
15682
|
-
1 /* StylingRange.NEXT_DUPLICATE */;
|
|
15681
|
+
return ((tStylingRange) & 1 /* StylingRange.NEXT_DUPLICATE */) === 1 /* StylingRange.NEXT_DUPLICATE */;
|
|
15683
15682
|
}
|
|
15684
15683
|
function setTStylingRangeNextDuplicate(tStylingRange) {
|
|
15685
15684
|
ngDevMode && assertNumber(tStylingRange, 'expected number');
|
|
@@ -17480,6 +17479,26 @@ function ɵɵclassMapInterpolateV(values) {
|
|
|
17480
17479
|
checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
|
|
17481
17480
|
}
|
|
17482
17481
|
|
|
17482
|
+
/*!
|
|
17483
|
+
* @license
|
|
17484
|
+
* Copyright Google LLC All Rights Reserved.
|
|
17485
|
+
*
|
|
17486
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
17487
|
+
* found in the LICENSE file at https://angular.io/license
|
|
17488
|
+
*/
|
|
17489
|
+
/**
|
|
17490
|
+
* Instruction that returns the component instance in which the current instruction is executing.
|
|
17491
|
+
* This is a constant-time version of `nextContent` for the case where we know that we need the
|
|
17492
|
+
* component instance specifically, rather than the context of a particular template.
|
|
17493
|
+
*
|
|
17494
|
+
* @codeGenApi
|
|
17495
|
+
*/
|
|
17496
|
+
function ɵɵcomponentInstance() {
|
|
17497
|
+
const instance = getLView()[DECLARATION_COMPONENT_VIEW][CONTEXT];
|
|
17498
|
+
ngDevMode && assertDefined(instance, 'Expected component instance to be defined');
|
|
17499
|
+
return instance;
|
|
17500
|
+
}
|
|
17501
|
+
|
|
17483
17502
|
class DefaultIterableDifferFactory {
|
|
17484
17503
|
constructor() { }
|
|
17485
17504
|
supports(obj) {
|
|
@@ -18620,7 +18639,7 @@ function createAndRenderEmbeddedLView(declarationLView, templateTNode, context,
|
|
|
18620
18639
|
// Embedded views follow the change detection strategy of the view they're declared in.
|
|
18621
18640
|
const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
18622
18641
|
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
18623
|
-
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, null, options?.injector ?? null, options?.
|
|
18642
|
+
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, null, options?.injector ?? null, options?.dehydratedView ?? null);
|
|
18624
18643
|
const declarationLContainer = declarationLView[templateTNode.index];
|
|
18625
18644
|
ngDevMode && assertLContainer(declarationLContainer);
|
|
18626
18645
|
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
@@ -18642,6 +18661,16 @@ function getLViewFromLContainer(lContainer, index) {
|
|
|
18642
18661
|
}
|
|
18643
18662
|
return undefined;
|
|
18644
18663
|
}
|
|
18664
|
+
/**
|
|
18665
|
+
* Returns whether an elements that belong to a view should be
|
|
18666
|
+
* inserted into the DOM. For client-only cases, DOM elements are
|
|
18667
|
+
* always inserted. For hydration cases, we check whether serialized
|
|
18668
|
+
* info is available for a view and the view is not in a "skip hydration"
|
|
18669
|
+
* block (in which case view contents was re-created, thus needing insertion).
|
|
18670
|
+
*/
|
|
18671
|
+
function shouldAddViewToDom(tNode, dehydratedView) {
|
|
18672
|
+
return !dehydratedView || hasInSkipHydrationBlockFlag(tNode);
|
|
18673
|
+
}
|
|
18645
18674
|
function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
|
|
18646
18675
|
const tView = lView[TVIEW];
|
|
18647
18676
|
// insert to the view tree so the new view can be change-detected
|
|
@@ -19539,12 +19568,28 @@ class RepeaterMetadata {
|
|
|
19539
19568
|
* - LView[HEADER_OFFSET + index + 2] - optional reference to a template function rendering an empty
|
|
19540
19569
|
* block
|
|
19541
19570
|
*
|
|
19571
|
+
* @param index Index at which to store the metadata of the repeater.
|
|
19572
|
+
* @param templateFn Reference to the template of the main repeater block.
|
|
19573
|
+
* @param decls The number of nodes, local refs, and pipes for the main block.
|
|
19574
|
+
* @param vars The number of bindings for the main block.
|
|
19575
|
+
* @param trackByFn Reference to the tracking function.
|
|
19576
|
+
* @param trackByUsesComponentInstance Whether the tracking function has any references to the
|
|
19577
|
+
* component instance. If it doesn't, we can avoid rebinding it.
|
|
19578
|
+
* @param emptyTemplateFn Reference to the template function of the empty block.
|
|
19579
|
+
* @param emptyDecls The number of nodes, local refs, and pipes for the empty block.
|
|
19580
|
+
* @param emptyVars The number of bindings for the empty block.
|
|
19581
|
+
*
|
|
19542
19582
|
* @codeGenApi
|
|
19543
19583
|
*/
|
|
19544
|
-
function ɵɵrepeaterCreate(index, templateFn, decls, vars, trackByFn, emptyTemplateFn, emptyDecls, emptyVars) {
|
|
19584
|
+
function ɵɵrepeaterCreate(index, templateFn, decls, vars, trackByFn, trackByUsesComponentInstance, emptyTemplateFn, emptyDecls, emptyVars) {
|
|
19545
19585
|
const hasEmptyBlock = emptyTemplateFn !== undefined;
|
|
19546
19586
|
const hostLView = getLView();
|
|
19547
|
-
const
|
|
19587
|
+
const boundTrackBy = trackByUsesComponentInstance ?
|
|
19588
|
+
// We only want to bind when necessary, because it produces a
|
|
19589
|
+
// new function. For pure functions it's not necessary.
|
|
19590
|
+
trackByFn.bind(hostLView[DECLARATION_COMPONENT_VIEW][CONTEXT]) :
|
|
19591
|
+
trackByFn;
|
|
19592
|
+
const metadata = new RepeaterMetadata(hasEmptyBlock, new DefaultIterableDiffer(boundTrackBy));
|
|
19548
19593
|
hostLView[HEADER_OFFSET + index] = metadata;
|
|
19549
19594
|
ɵɵtemplate(index + 1, templateFn, decls, vars);
|
|
19550
19595
|
if (hasEmptyBlock) {
|
|
@@ -19655,142 +19700,741 @@ function getExistingTNode(tView, index) {
|
|
|
19655
19700
|
return tNode;
|
|
19656
19701
|
}
|
|
19657
19702
|
|
|
19658
|
-
const DEFER_BLOCK_STATE = 0;
|
|
19659
|
-
|
|
19660
|
-
/**
|
|
19661
|
-
* Shims for the `requestIdleCallback` and `cancelIdleCallback` functions for environments
|
|
19662
|
-
* where those functions are not available (e.g. Node.js).
|
|
19663
|
-
*/
|
|
19664
|
-
const _requestIdleCallback = typeof requestIdleCallback !== 'undefined' ? requestIdleCallback : setTimeout;
|
|
19665
|
-
const _cancelIdleCallback = typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback : clearTimeout;
|
|
19666
19703
|
/**
|
|
19667
|
-
*
|
|
19668
|
-
*
|
|
19669
|
-
*
|
|
19670
|
-
* @param primaryTmplIndex Index of the template with the primary block content.
|
|
19671
|
-
* @param dependencyResolverFn Function that contains dependencies for this defer block.
|
|
19672
|
-
* @param loadingTmplIndex Index of the template with the `{:loading}` block content.
|
|
19673
|
-
* @param placeholderTmplIndex Index of the template with the `{:placeholder}` block content.
|
|
19674
|
-
* @param errorTmplIndex Index of the template with the `{:error}` block content.
|
|
19675
|
-
* @param loadingConfigIndex Index in the constants array of the configuration of the `{:loading}`.
|
|
19676
|
-
* block.
|
|
19677
|
-
* @param placeholderConfigIndexIndex in the constants array of the configuration of the
|
|
19678
|
-
* `{:placeholder}` block.
|
|
19679
|
-
*
|
|
19680
|
-
* @codeGenApi
|
|
19704
|
+
* Removes all dehydrated views from a given LContainer:
|
|
19705
|
+
* both in internal data structure, as well as removing
|
|
19706
|
+
* corresponding DOM nodes that belong to that dehydrated view.
|
|
19681
19707
|
*/
|
|
19682
|
-
function
|
|
19683
|
-
const
|
|
19684
|
-
const
|
|
19685
|
-
const
|
|
19686
|
-
const
|
|
19687
|
-
|
|
19688
|
-
|
|
19689
|
-
const deferBlockConfig = {
|
|
19690
|
-
primaryTmplIndex,
|
|
19691
|
-
loadingTmplIndex: loadingTmplIndex ?? null,
|
|
19692
|
-
placeholderTmplIndex: placeholderTmplIndex ?? null,
|
|
19693
|
-
errorTmplIndex: errorTmplIndex ?? null,
|
|
19694
|
-
placeholderBlockConfig: placeholderConfigIndex != null ?
|
|
19695
|
-
getConstant(tViewConsts, placeholderConfigIndex) :
|
|
19696
|
-
null,
|
|
19697
|
-
loadingBlockConfig: loadingConfigIndex != null ?
|
|
19698
|
-
getConstant(tViewConsts, loadingConfigIndex) :
|
|
19699
|
-
null,
|
|
19700
|
-
dependencyResolverFn: dependencyResolverFn ?? null,
|
|
19701
|
-
loadingState: 0 /* DeferDependenciesLoadingState.NOT_STARTED */,
|
|
19702
|
-
loadingPromise: null,
|
|
19703
|
-
};
|
|
19704
|
-
setTDeferBlockDetails(tView, adjustedIndex, deferBlockConfig);
|
|
19708
|
+
function removeDehydratedViews(lContainer) {
|
|
19709
|
+
const views = lContainer[DEHYDRATED_VIEWS] ?? [];
|
|
19710
|
+
const parentLView = lContainer[PARENT];
|
|
19711
|
+
const renderer = parentLView[RENDERER];
|
|
19712
|
+
for (const view of views) {
|
|
19713
|
+
removeDehydratedView(view, renderer);
|
|
19714
|
+
ngDevMode && ngDevMode.dehydratedViewsRemoved++;
|
|
19705
19715
|
}
|
|
19706
|
-
//
|
|
19707
|
-
|
|
19708
|
-
|
|
19709
|
-
|
|
19716
|
+
// Reset the value to an empty array to indicate that no
|
|
19717
|
+
// further processing of dehydrated views is needed for
|
|
19718
|
+
// this view container (i.e. do not trigger the lookup process
|
|
19719
|
+
// once again in case a `ViewContainerRef` is created later).
|
|
19720
|
+
lContainer[DEHYDRATED_VIEWS] = EMPTY_ARRAY;
|
|
19710
19721
|
}
|
|
19711
19722
|
/**
|
|
19712
|
-
*
|
|
19713
|
-
* @codeGenApi
|
|
19723
|
+
* Helper function to remove all nodes from a dehydrated view.
|
|
19714
19724
|
*/
|
|
19715
|
-
function
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
if (
|
|
19719
|
-
const
|
|
19720
|
-
|
|
19721
|
-
|
|
19722
|
-
|
|
19723
|
-
|
|
19724
|
-
|
|
19725
|
-
|
|
19726
|
-
}
|
|
19727
|
-
else if (value === true &&
|
|
19728
|
-
(renderedState === 0 /* DeferBlockInstanceState.INITIAL */ ||
|
|
19729
|
-
renderedState === 1 /* DeferBlockInstanceState.PLACEHOLDER */)) {
|
|
19730
|
-
// The `when` condition has changed to `true`, trigger defer block loading
|
|
19731
|
-
// if the block is either in initial (nothing is rendered) or a placeholder
|
|
19732
|
-
// state.
|
|
19733
|
-
triggerDeferBlock(lView, tNode);
|
|
19725
|
+
function removeDehydratedView(dehydratedView, renderer) {
|
|
19726
|
+
let nodesRemoved = 0;
|
|
19727
|
+
let currentRNode = dehydratedView.firstChild;
|
|
19728
|
+
if (currentRNode) {
|
|
19729
|
+
const numNodes = dehydratedView.data[NUM_ROOT_NODES];
|
|
19730
|
+
while (nodesRemoved < numNodes) {
|
|
19731
|
+
ngDevMode && validateSiblingNodeExists(currentRNode);
|
|
19732
|
+
const nextSibling = currentRNode.nextSibling;
|
|
19733
|
+
nativeRemoveNode(renderer, currentRNode, false);
|
|
19734
|
+
currentRNode = nextSibling;
|
|
19735
|
+
nodesRemoved++;
|
|
19734
19736
|
}
|
|
19735
19737
|
}
|
|
19736
19738
|
}
|
|
19737
19739
|
/**
|
|
19738
|
-
*
|
|
19739
|
-
*
|
|
19740
|
+
* Walks over all views within this LContainer invokes dehydrated views
|
|
19741
|
+
* cleanup function for each one.
|
|
19740
19742
|
*/
|
|
19741
|
-
function
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
const value = Boolean(rawValue); // handle truthy or falsy values
|
|
19746
|
-
const tView = lView[TVIEW];
|
|
19747
|
-
const tNode = getSelectedTNode();
|
|
19748
|
-
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
19749
|
-
if (value === true && tDetails.loadingState === 0 /* DeferDependenciesLoadingState.NOT_STARTED */) {
|
|
19750
|
-
// If loading has not been started yet, trigger it now.
|
|
19751
|
-
triggerResourceLoading(tDetails, getPrimaryBlockTNode(tView, tDetails), lView[INJECTOR$1]);
|
|
19752
|
-
}
|
|
19743
|
+
function cleanupLContainer(lContainer) {
|
|
19744
|
+
removeDehydratedViews(lContainer);
|
|
19745
|
+
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
19746
|
+
cleanupLView(lContainer[i]);
|
|
19753
19747
|
}
|
|
19754
19748
|
}
|
|
19755
19749
|
/**
|
|
19756
|
-
*
|
|
19757
|
-
*
|
|
19750
|
+
* Walks over `LContainer`s and components registered within
|
|
19751
|
+
* this LView and invokes dehydrated views cleanup function for each one.
|
|
19758
19752
|
*/
|
|
19759
|
-
function
|
|
19760
|
-
const
|
|
19761
|
-
|
|
19762
|
-
|
|
19763
|
-
|
|
19764
|
-
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
});
|
|
19772
|
-
// Store a cleanup function on LView, so that we cancel idle
|
|
19773
|
-
// callback in case this LView was destroyed before a callback
|
|
19774
|
-
// was invoked.
|
|
19775
|
-
storeLViewOnDestroy(lView, removeIdleCallback);
|
|
19753
|
+
function cleanupLView(lView) {
|
|
19754
|
+
const tView = lView[TVIEW];
|
|
19755
|
+
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
19756
|
+
if (isLContainer(lView[i])) {
|
|
19757
|
+
const lContainer = lView[i];
|
|
19758
|
+
cleanupLContainer(lContainer);
|
|
19759
|
+
}
|
|
19760
|
+
else if (isLView(lView[i])) {
|
|
19761
|
+
// This is a component, enter the `cleanupLView` recursively.
|
|
19762
|
+
cleanupLView(lView[i]);
|
|
19763
|
+
}
|
|
19764
|
+
}
|
|
19776
19765
|
}
|
|
19777
19766
|
/**
|
|
19778
|
-
*
|
|
19779
|
-
*
|
|
19780
|
-
*/
|
|
19781
|
-
function ɵɵdeferPrefetchOnIdle() { } // TODO: implement runtime logic.
|
|
19782
|
-
/**
|
|
19783
|
-
* Creates runtime data structures for the `on immediate` deferred trigger.
|
|
19784
|
-
* @codeGenApi
|
|
19767
|
+
* Walks over all views registered within the ApplicationRef and removes
|
|
19768
|
+
* all dehydrated views from all `LContainer`s along the way.
|
|
19785
19769
|
*/
|
|
19786
|
-
function
|
|
19770
|
+
function cleanupDehydratedViews(appRef) {
|
|
19771
|
+
const viewRefs = appRef._views;
|
|
19772
|
+
for (const viewRef of viewRefs) {
|
|
19773
|
+
const lNode = getLNodeForHydration(viewRef);
|
|
19774
|
+
// An `lView` might be `null` if a `ViewRef` represents
|
|
19775
|
+
// an embedded view (not a component view).
|
|
19776
|
+
if (lNode !== null && lNode[HOST] !== null) {
|
|
19777
|
+
if (isLView(lNode)) {
|
|
19778
|
+
cleanupLView(lNode);
|
|
19779
|
+
}
|
|
19780
|
+
else {
|
|
19781
|
+
// Cleanup in the root component view
|
|
19782
|
+
const componentLView = lNode[HOST];
|
|
19783
|
+
cleanupLView(componentLView);
|
|
19784
|
+
// Cleanup in all views within this view container
|
|
19785
|
+
cleanupLContainer(lNode);
|
|
19786
|
+
}
|
|
19787
|
+
ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
|
|
19788
|
+
}
|
|
19789
|
+
}
|
|
19790
|
+
}
|
|
19791
|
+
|
|
19787
19792
|
/**
|
|
19788
|
-
*
|
|
19789
|
-
*
|
|
19793
|
+
* Given a current DOM node and a serialized information about the views
|
|
19794
|
+
* in a container, walks over the DOM structure, collecting the list of
|
|
19795
|
+
* dehydrated views.
|
|
19790
19796
|
*/
|
|
19791
|
-
function
|
|
19792
|
-
|
|
19793
|
-
|
|
19797
|
+
function locateDehydratedViewsInContainer(currentRNode, serializedViews) {
|
|
19798
|
+
const dehydratedViews = [];
|
|
19799
|
+
for (const serializedView of serializedViews) {
|
|
19800
|
+
// Repeats a view multiple times as needed, based on the serialized information
|
|
19801
|
+
// (for example, for *ngFor-produced views).
|
|
19802
|
+
for (let i = 0; i < (serializedView[MULTIPLIER] ?? 1); i++) {
|
|
19803
|
+
const view = {
|
|
19804
|
+
data: serializedView,
|
|
19805
|
+
firstChild: null,
|
|
19806
|
+
};
|
|
19807
|
+
if (serializedView[NUM_ROOT_NODES] > 0) {
|
|
19808
|
+
// Keep reference to the first node in this view,
|
|
19809
|
+
// so it can be accessed while invoking template instructions.
|
|
19810
|
+
view.firstChild = currentRNode;
|
|
19811
|
+
// Move over to the next node after this view, which can
|
|
19812
|
+
// either be a first node of the next view or an anchor comment
|
|
19813
|
+
// node after the last view in a container.
|
|
19814
|
+
currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
|
|
19815
|
+
}
|
|
19816
|
+
dehydratedViews.push(view);
|
|
19817
|
+
}
|
|
19818
|
+
}
|
|
19819
|
+
return [currentRNode, dehydratedViews];
|
|
19820
|
+
}
|
|
19821
|
+
/**
|
|
19822
|
+
* Reference to a function that searches for a matching dehydrated views
|
|
19823
|
+
* stored on a given lContainer.
|
|
19824
|
+
* Returns `null` by default, when hydration is not enabled.
|
|
19825
|
+
*/
|
|
19826
|
+
let _findMatchingDehydratedViewImpl = (lContainer, template) => null;
|
|
19827
|
+
/**
|
|
19828
|
+
* Retrieves the next dehydrated view from the LContainer and verifies that
|
|
19829
|
+
* it matches a given template id (from the TView that was used to create this
|
|
19830
|
+
* instance of a view). If the id doesn't match, that means that we are in an
|
|
19831
|
+
* unexpected state and can not complete the reconciliation process. Thus,
|
|
19832
|
+
* all dehydrated views from this LContainer are removed (including corresponding
|
|
19833
|
+
* DOM nodes) and the rendering is performed as if there were no dehydrated views
|
|
19834
|
+
* in this container.
|
|
19835
|
+
*/
|
|
19836
|
+
function findMatchingDehydratedViewImpl(lContainer, template) {
|
|
19837
|
+
const views = lContainer[DEHYDRATED_VIEWS] ?? [];
|
|
19838
|
+
if (!template || views.length === 0) {
|
|
19839
|
+
return null;
|
|
19840
|
+
}
|
|
19841
|
+
const view = views[0];
|
|
19842
|
+
// Verify whether the first dehydrated view in the container matches
|
|
19843
|
+
// the template id passed to this function (that originated from a TView
|
|
19844
|
+
// that was used to create an instance of an embedded or component views.
|
|
19845
|
+
if (view.data[TEMPLATE_ID] === template) {
|
|
19846
|
+
// If the template id matches - extract the first view and return it.
|
|
19847
|
+
return views.shift();
|
|
19848
|
+
}
|
|
19849
|
+
else {
|
|
19850
|
+
// Otherwise, we are at the state when reconciliation can not be completed,
|
|
19851
|
+
// thus we remove all dehydrated views within this container (remove them
|
|
19852
|
+
// from internal data structures as well as delete associated elements from
|
|
19853
|
+
// the DOM tree).
|
|
19854
|
+
removeDehydratedViews(lContainer);
|
|
19855
|
+
return null;
|
|
19856
|
+
}
|
|
19857
|
+
}
|
|
19858
|
+
function enableFindMatchingDehydratedViewImpl() {
|
|
19859
|
+
_findMatchingDehydratedViewImpl = findMatchingDehydratedViewImpl;
|
|
19860
|
+
}
|
|
19861
|
+
function findMatchingDehydratedView(lContainer, template) {
|
|
19862
|
+
return _findMatchingDehydratedViewImpl(lContainer, template);
|
|
19863
|
+
}
|
|
19864
|
+
|
|
19865
|
+
/**
|
|
19866
|
+
* Represents a container where one or more views can be attached to a component.
|
|
19867
|
+
*
|
|
19868
|
+
* Can contain *host views* (created by instantiating a
|
|
19869
|
+
* component with the `createComponent()` method), and *embedded views*
|
|
19870
|
+
* (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
|
|
19871
|
+
*
|
|
19872
|
+
* A view container instance can contain other view containers,
|
|
19873
|
+
* creating a [view hierarchy](guide/glossary#view-hierarchy).
|
|
19874
|
+
*
|
|
19875
|
+
* @usageNotes
|
|
19876
|
+
*
|
|
19877
|
+
* The example below demonstrates how the `createComponent` function can be used
|
|
19878
|
+
* to create an instance of a ComponentRef dynamically and attach it to an ApplicationRef,
|
|
19879
|
+
* so that it gets included into change detection cycles.
|
|
19880
|
+
*
|
|
19881
|
+
* Note: the example uses standalone components, but the function can also be used for
|
|
19882
|
+
* non-standalone components (declared in an NgModule) as well.
|
|
19883
|
+
*
|
|
19884
|
+
* ```typescript
|
|
19885
|
+
* @Component({
|
|
19886
|
+
* standalone: true,
|
|
19887
|
+
* selector: 'dynamic',
|
|
19888
|
+
* template: `<span>This is a content of a dynamic component.</span>`,
|
|
19889
|
+
* })
|
|
19890
|
+
* class DynamicComponent {
|
|
19891
|
+
* vcr = inject(ViewContainerRef);
|
|
19892
|
+
* }
|
|
19893
|
+
*
|
|
19894
|
+
* @Component({
|
|
19895
|
+
* standalone: true,
|
|
19896
|
+
* selector: 'app',
|
|
19897
|
+
* template: `<main>Hi! This is the main content.</main>`,
|
|
19898
|
+
* })
|
|
19899
|
+
* class AppComponent {
|
|
19900
|
+
* vcr = inject(ViewContainerRef);
|
|
19901
|
+
*
|
|
19902
|
+
* ngAfterViewInit() {
|
|
19903
|
+
* const compRef = this.vcr.createComponent(DynamicComponent);
|
|
19904
|
+
* compRef.changeDetectorRef.detectChanges();
|
|
19905
|
+
* }
|
|
19906
|
+
* }
|
|
19907
|
+
* ```
|
|
19908
|
+
*
|
|
19909
|
+
* @see {@link ComponentRef}
|
|
19910
|
+
* @see {@link EmbeddedViewRef}
|
|
19911
|
+
*
|
|
19912
|
+
* @publicApi
|
|
19913
|
+
*/
|
|
19914
|
+
class ViewContainerRef {
|
|
19915
|
+
/**
|
|
19916
|
+
* @internal
|
|
19917
|
+
* @nocollapse
|
|
19918
|
+
*/
|
|
19919
|
+
static { this.__NG_ELEMENT_ID__ = injectViewContainerRef; }
|
|
19920
|
+
}
|
|
19921
|
+
/**
|
|
19922
|
+
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
|
|
19923
|
+
* already exists, retrieves the existing ViewContainerRef.
|
|
19924
|
+
*
|
|
19925
|
+
* @returns The ViewContainerRef instance to use
|
|
19926
|
+
*/
|
|
19927
|
+
function injectViewContainerRef() {
|
|
19928
|
+
const previousTNode = getCurrentTNode();
|
|
19929
|
+
return createContainerRef(previousTNode, getLView());
|
|
19930
|
+
}
|
|
19931
|
+
const VE_ViewContainerRef = ViewContainerRef;
|
|
19932
|
+
// TODO(alxhub): cleaning up this indirection triggers a subtle bug in Closure in g3. Once the fix
|
|
19933
|
+
// for that lands, this can be cleaned up.
|
|
19934
|
+
const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
19935
|
+
constructor(_lContainer, _hostTNode, _hostLView) {
|
|
19936
|
+
super();
|
|
19937
|
+
this._lContainer = _lContainer;
|
|
19938
|
+
this._hostTNode = _hostTNode;
|
|
19939
|
+
this._hostLView = _hostLView;
|
|
19940
|
+
}
|
|
19941
|
+
get element() {
|
|
19942
|
+
return createElementRef(this._hostTNode, this._hostLView);
|
|
19943
|
+
}
|
|
19944
|
+
get injector() {
|
|
19945
|
+
return new NodeInjector(this._hostTNode, this._hostLView);
|
|
19946
|
+
}
|
|
19947
|
+
/** @deprecated No replacement */
|
|
19948
|
+
get parentInjector() {
|
|
19949
|
+
const parentLocation = getParentInjectorLocation(this._hostTNode, this._hostLView);
|
|
19950
|
+
if (hasParentInjector(parentLocation)) {
|
|
19951
|
+
const parentView = getParentInjectorView(parentLocation, this._hostLView);
|
|
19952
|
+
const injectorIndex = getParentInjectorIndex(parentLocation);
|
|
19953
|
+
ngDevMode && assertNodeInjector(parentView, injectorIndex);
|
|
19954
|
+
const parentTNode = parentView[TVIEW].data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */];
|
|
19955
|
+
return new NodeInjector(parentTNode, parentView);
|
|
19956
|
+
}
|
|
19957
|
+
else {
|
|
19958
|
+
return new NodeInjector(null, this._hostLView);
|
|
19959
|
+
}
|
|
19960
|
+
}
|
|
19961
|
+
clear() {
|
|
19962
|
+
while (this.length > 0) {
|
|
19963
|
+
this.remove(this.length - 1);
|
|
19964
|
+
}
|
|
19965
|
+
}
|
|
19966
|
+
get(index) {
|
|
19967
|
+
const viewRefs = getViewRefs(this._lContainer);
|
|
19968
|
+
return viewRefs !== null && viewRefs[index] || null;
|
|
19969
|
+
}
|
|
19970
|
+
get length() {
|
|
19971
|
+
return this._lContainer.length - CONTAINER_HEADER_OFFSET;
|
|
19972
|
+
}
|
|
19973
|
+
createEmbeddedView(templateRef, context, indexOrOptions) {
|
|
19974
|
+
let index;
|
|
19975
|
+
let injector;
|
|
19976
|
+
if (typeof indexOrOptions === 'number') {
|
|
19977
|
+
index = indexOrOptions;
|
|
19978
|
+
}
|
|
19979
|
+
else if (indexOrOptions != null) {
|
|
19980
|
+
index = indexOrOptions.index;
|
|
19981
|
+
injector = indexOrOptions.injector;
|
|
19982
|
+
}
|
|
19983
|
+
const dehydratedView = findMatchingDehydratedView(this._lContainer, templateRef.ssrId);
|
|
19984
|
+
const viewRef = templateRef.createEmbeddedViewImpl(context || {}, injector, dehydratedView);
|
|
19985
|
+
this.insertImpl(viewRef, index, shouldAddViewToDom(this._hostTNode, dehydratedView));
|
|
19986
|
+
return viewRef;
|
|
19987
|
+
}
|
|
19988
|
+
createComponent(componentFactoryOrType, indexOrOptions, injector, projectableNodes, environmentInjector) {
|
|
19989
|
+
const isComponentFactory = componentFactoryOrType && !isType(componentFactoryOrType);
|
|
19990
|
+
let index;
|
|
19991
|
+
// This function supports 2 signatures and we need to handle options correctly for both:
|
|
19992
|
+
// 1. When first argument is a Component type. This signature also requires extra
|
|
19993
|
+
// options to be provided as object (more ergonomic option).
|
|
19994
|
+
// 2. First argument is a Component factory. In this case extra options are represented as
|
|
19995
|
+
// positional arguments. This signature is less ergonomic and will be deprecated.
|
|
19996
|
+
if (isComponentFactory) {
|
|
19997
|
+
if (ngDevMode) {
|
|
19998
|
+
assertEqual(typeof indexOrOptions !== 'object', true, 'It looks like Component factory was provided as the first argument ' +
|
|
19999
|
+
'and an options object as the second argument. This combination of arguments ' +
|
|
20000
|
+
'is incompatible. You can either change the first argument to provide Component ' +
|
|
20001
|
+
'type or change the second argument to be a number (representing an index at ' +
|
|
20002
|
+
'which to insert the new component\'s host view into this container)');
|
|
20003
|
+
}
|
|
20004
|
+
index = indexOrOptions;
|
|
20005
|
+
}
|
|
20006
|
+
else {
|
|
20007
|
+
if (ngDevMode) {
|
|
20008
|
+
assertDefined(getComponentDef(componentFactoryOrType), `Provided Component class doesn't contain Component definition. ` +
|
|
20009
|
+
`Please check whether provided class has @Component decorator.`);
|
|
20010
|
+
assertEqual(typeof indexOrOptions !== 'number', true, 'It looks like Component type was provided as the first argument ' +
|
|
20011
|
+
'and a number (representing an index at which to insert the new component\'s ' +
|
|
20012
|
+
'host view into this container as the second argument. This combination of arguments ' +
|
|
20013
|
+
'is incompatible. Please use an object as the second argument instead.');
|
|
20014
|
+
}
|
|
20015
|
+
const options = (indexOrOptions || {});
|
|
20016
|
+
if (ngDevMode && options.environmentInjector && options.ngModuleRef) {
|
|
20017
|
+
throwError(`Cannot pass both environmentInjector and ngModuleRef options to createComponent().`);
|
|
20018
|
+
}
|
|
20019
|
+
index = options.index;
|
|
20020
|
+
injector = options.injector;
|
|
20021
|
+
projectableNodes = options.projectableNodes;
|
|
20022
|
+
environmentInjector = options.environmentInjector || options.ngModuleRef;
|
|
20023
|
+
}
|
|
20024
|
+
const componentFactory = isComponentFactory ?
|
|
20025
|
+
componentFactoryOrType :
|
|
20026
|
+
new ComponentFactory(getComponentDef(componentFactoryOrType));
|
|
20027
|
+
const contextInjector = injector || this.parentInjector;
|
|
20028
|
+
// If an `NgModuleRef` is not provided explicitly, try retrieving it from the DI tree.
|
|
20029
|
+
if (!environmentInjector && componentFactory.ngModule == null) {
|
|
20030
|
+
// For the `ComponentFactory` case, entering this logic is very unlikely, since we expect that
|
|
20031
|
+
// an instance of a `ComponentFactory`, resolved via `ComponentFactoryResolver` would have an
|
|
20032
|
+
// `ngModule` field. This is possible in some test scenarios and potentially in some JIT-based
|
|
20033
|
+
// use-cases. For the `ComponentFactory` case we preserve backwards-compatibility and try
|
|
20034
|
+
// using a provided injector first, then fall back to the parent injector of this
|
|
20035
|
+
// `ViewContainerRef` instance.
|
|
20036
|
+
//
|
|
20037
|
+
// For the factory-less case, it's critical to establish a connection with the module
|
|
20038
|
+
// injector tree (by retrieving an instance of an `NgModuleRef` and accessing its injector),
|
|
20039
|
+
// so that a component can use DI tokens provided in MgModules. For this reason, we can not
|
|
20040
|
+
// rely on the provided injector, since it might be detached from the DI tree (for example, if
|
|
20041
|
+
// it was created via `Injector.create` without specifying a parent injector, or if an
|
|
20042
|
+
// injector is retrieved from an `NgModuleRef` created via `createNgModule` using an
|
|
20043
|
+
// NgModule outside of a module tree). Instead, we always use `ViewContainerRef`'s parent
|
|
20044
|
+
// injector, which is normally connected to the DI tree, which includes module injector
|
|
20045
|
+
// subtree.
|
|
20046
|
+
const _injector = isComponentFactory ? contextInjector : this.parentInjector;
|
|
20047
|
+
// DO NOT REFACTOR. The code here used to have a `injector.get(NgModuleRef, null) ||
|
|
20048
|
+
// undefined` expression which seems to cause internal google apps to fail. This is documented
|
|
20049
|
+
// in the following internal bug issue: go/b/142967802
|
|
20050
|
+
const result = _injector.get(EnvironmentInjector, null);
|
|
20051
|
+
if (result) {
|
|
20052
|
+
environmentInjector = result;
|
|
20053
|
+
}
|
|
20054
|
+
}
|
|
20055
|
+
const componentDef = getComponentDef(componentFactory.componentType ?? {});
|
|
20056
|
+
const dehydratedView = findMatchingDehydratedView(this._lContainer, componentDef?.id ?? null);
|
|
20057
|
+
const rNode = dehydratedView?.firstChild ?? null;
|
|
20058
|
+
const componentRef = componentFactory.create(contextInjector, projectableNodes, rNode, environmentInjector);
|
|
20059
|
+
this.insertImpl(componentRef.hostView, index, shouldAddViewToDom(this._hostTNode, dehydratedView));
|
|
20060
|
+
return componentRef;
|
|
20061
|
+
}
|
|
20062
|
+
insert(viewRef, index) {
|
|
20063
|
+
return this.insertImpl(viewRef, index, true);
|
|
20064
|
+
}
|
|
20065
|
+
insertImpl(viewRef, index, addToDOM) {
|
|
20066
|
+
const lView = viewRef._lView;
|
|
20067
|
+
if (ngDevMode && viewRef.destroyed) {
|
|
20068
|
+
throw new Error('Cannot insert a destroyed View in a ViewContainer!');
|
|
20069
|
+
}
|
|
20070
|
+
if (viewAttachedToContainer(lView)) {
|
|
20071
|
+
// If view is already attached, detach it first so we clean up references appropriately.
|
|
20072
|
+
const prevIdx = this.indexOf(viewRef);
|
|
20073
|
+
// A view might be attached either to this or a different container. The `prevIdx` for
|
|
20074
|
+
// those cases will be:
|
|
20075
|
+
// equal to -1 for views attached to this ViewContainerRef
|
|
20076
|
+
// >= 0 for views attached to a different ViewContainerRef
|
|
20077
|
+
if (prevIdx !== -1) {
|
|
20078
|
+
this.detach(prevIdx);
|
|
20079
|
+
}
|
|
20080
|
+
else {
|
|
20081
|
+
const prevLContainer = lView[PARENT];
|
|
20082
|
+
ngDevMode &&
|
|
20083
|
+
assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.');
|
|
20084
|
+
// We need to re-create a R3ViewContainerRef instance since those are not stored on
|
|
20085
|
+
// LView (nor anywhere else).
|
|
20086
|
+
const prevVCRef = new R3ViewContainerRef(prevLContainer, prevLContainer[T_HOST], prevLContainer[PARENT]);
|
|
20087
|
+
prevVCRef.detach(prevVCRef.indexOf(viewRef));
|
|
20088
|
+
}
|
|
20089
|
+
}
|
|
20090
|
+
// Logical operation of adding `LView` to `LContainer`
|
|
20091
|
+
const adjustedIdx = this._adjustIndex(index);
|
|
20092
|
+
const lContainer = this._lContainer;
|
|
20093
|
+
addLViewToLContainer(lContainer, lView, adjustedIdx, addToDOM);
|
|
20094
|
+
viewRef.attachToViewContainerRef();
|
|
20095
|
+
addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
|
|
20096
|
+
return viewRef;
|
|
20097
|
+
}
|
|
20098
|
+
move(viewRef, newIndex) {
|
|
20099
|
+
if (ngDevMode && viewRef.destroyed) {
|
|
20100
|
+
throw new Error('Cannot move a destroyed View in a ViewContainer!');
|
|
20101
|
+
}
|
|
20102
|
+
return this.insert(viewRef, newIndex);
|
|
20103
|
+
}
|
|
20104
|
+
indexOf(viewRef) {
|
|
20105
|
+
const viewRefsArr = getViewRefs(this._lContainer);
|
|
20106
|
+
return viewRefsArr !== null ? viewRefsArr.indexOf(viewRef) : -1;
|
|
20107
|
+
}
|
|
20108
|
+
remove(index) {
|
|
20109
|
+
const adjustedIdx = this._adjustIndex(index, -1);
|
|
20110
|
+
const detachedView = detachView(this._lContainer, adjustedIdx);
|
|
20111
|
+
if (detachedView) {
|
|
20112
|
+
// Before destroying the view, remove it from the container's array of `ViewRef`s.
|
|
20113
|
+
// This ensures the view container length is updated before calling
|
|
20114
|
+
// `destroyLView`, which could recursively call view container methods that
|
|
20115
|
+
// rely on an accurate container length.
|
|
20116
|
+
// (e.g. a method on this view container being called by a child directive's OnDestroy
|
|
20117
|
+
// lifecycle hook)
|
|
20118
|
+
removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx);
|
|
20119
|
+
destroyLView(detachedView[TVIEW], detachedView);
|
|
20120
|
+
}
|
|
20121
|
+
}
|
|
20122
|
+
detach(index) {
|
|
20123
|
+
const adjustedIdx = this._adjustIndex(index, -1);
|
|
20124
|
+
const view = detachView(this._lContainer, adjustedIdx);
|
|
20125
|
+
const wasDetached = view && removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx) != null;
|
|
20126
|
+
return wasDetached ? new ViewRef$1(view) : null;
|
|
20127
|
+
}
|
|
20128
|
+
_adjustIndex(index, shift = 0) {
|
|
20129
|
+
if (index == null) {
|
|
20130
|
+
return this.length + shift;
|
|
20131
|
+
}
|
|
20132
|
+
if (ngDevMode) {
|
|
20133
|
+
assertGreaterThan(index, -1, `ViewRef index must be positive, got ${index}`);
|
|
20134
|
+
// +1 because it's legal to insert at the end.
|
|
20135
|
+
assertLessThan(index, this.length + 1 + shift, 'index');
|
|
20136
|
+
}
|
|
20137
|
+
return index;
|
|
20138
|
+
}
|
|
20139
|
+
};
|
|
20140
|
+
function getViewRefs(lContainer) {
|
|
20141
|
+
return lContainer[VIEW_REFS];
|
|
20142
|
+
}
|
|
20143
|
+
function getOrCreateViewRefs(lContainer) {
|
|
20144
|
+
return (lContainer[VIEW_REFS] || (lContainer[VIEW_REFS] = []));
|
|
20145
|
+
}
|
|
20146
|
+
/**
|
|
20147
|
+
* Creates a ViewContainerRef and stores it on the injector.
|
|
20148
|
+
*
|
|
20149
|
+
* @param hostTNode The node that is requesting a ViewContainerRef
|
|
20150
|
+
* @param hostLView The view to which the node belongs
|
|
20151
|
+
* @returns The ViewContainerRef instance to use
|
|
20152
|
+
*/
|
|
20153
|
+
function createContainerRef(hostTNode, hostLView) {
|
|
20154
|
+
ngDevMode && assertTNodeType(hostTNode, 12 /* TNodeType.AnyContainer */ | 3 /* TNodeType.AnyRNode */);
|
|
20155
|
+
let lContainer;
|
|
20156
|
+
const slotValue = hostLView[hostTNode.index];
|
|
20157
|
+
if (isLContainer(slotValue)) {
|
|
20158
|
+
// If the host is a container, we don't need to create a new LContainer
|
|
20159
|
+
lContainer = slotValue;
|
|
20160
|
+
}
|
|
20161
|
+
else {
|
|
20162
|
+
// An LContainer anchor can not be `null`, but we set it here temporarily
|
|
20163
|
+
// and update to the actual value later in this function (see
|
|
20164
|
+
// `_locateOrCreateAnchorNode`).
|
|
20165
|
+
lContainer = createLContainer(slotValue, hostLView, null, hostTNode);
|
|
20166
|
+
hostLView[hostTNode.index] = lContainer;
|
|
20167
|
+
addToViewTree(hostLView, lContainer);
|
|
20168
|
+
}
|
|
20169
|
+
_locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue);
|
|
20170
|
+
return new R3ViewContainerRef(lContainer, hostTNode, hostLView);
|
|
20171
|
+
}
|
|
20172
|
+
/**
|
|
20173
|
+
* Creates and inserts a comment node that acts as an anchor for a view container.
|
|
20174
|
+
*
|
|
20175
|
+
* If the host is a regular element, we have to insert a comment node manually which will
|
|
20176
|
+
* be used as an anchor when inserting elements. In this specific case we use low-level DOM
|
|
20177
|
+
* manipulation to insert it.
|
|
20178
|
+
*/
|
|
20179
|
+
function insertAnchorNode(hostLView, hostTNode) {
|
|
20180
|
+
const renderer = hostLView[RENDERER];
|
|
20181
|
+
ngDevMode && ngDevMode.rendererCreateComment++;
|
|
20182
|
+
const commentNode = renderer.createComment(ngDevMode ? 'container' : '');
|
|
20183
|
+
const hostNative = getNativeByTNode(hostTNode, hostLView);
|
|
20184
|
+
const parentOfHostNative = nativeParentNode(renderer, hostNative);
|
|
20185
|
+
nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative), false);
|
|
20186
|
+
return commentNode;
|
|
20187
|
+
}
|
|
20188
|
+
let _locateOrCreateAnchorNode = createAnchorNode;
|
|
20189
|
+
let _populateDehydratedViewsInContainer = (lContainer, lView, tNode) => false; // noop by default
|
|
20190
|
+
/**
|
|
20191
|
+
* Looks up dehydrated views that belong to a given LContainer and populates
|
|
20192
|
+
* this information into the `LContainer[DEHYDRATED_VIEWS]` slot. When running
|
|
20193
|
+
* in client-only mode, this function is a noop.
|
|
20194
|
+
*
|
|
20195
|
+
* @param lContainer LContainer that should be populated.
|
|
20196
|
+
* @returns a boolean flag that indicates whether a populating operation
|
|
20197
|
+
* was successful. The operation might be unsuccessful in case is has completed
|
|
20198
|
+
* previously, we are rendering in client-only mode or this content is located
|
|
20199
|
+
* in a skip hydration section.
|
|
20200
|
+
*/
|
|
20201
|
+
function populateDehydratedViewsInContainer(lContainer) {
|
|
20202
|
+
return _populateDehydratedViewsInContainer(lContainer, getLView(), getCurrentTNode());
|
|
20203
|
+
}
|
|
20204
|
+
/**
|
|
20205
|
+
* Regular creation mode: an anchor is created and
|
|
20206
|
+
* assigned to the `lContainer[NATIVE]` slot.
|
|
20207
|
+
*/
|
|
20208
|
+
function createAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
|
|
20209
|
+
// We already have a native element (anchor) set, return.
|
|
20210
|
+
if (lContainer[NATIVE])
|
|
20211
|
+
return;
|
|
20212
|
+
let commentNode;
|
|
20213
|
+
// If the host is an element container, the native host element is guaranteed to be a
|
|
20214
|
+
// comment and we can reuse that comment as anchor element for the new LContainer.
|
|
20215
|
+
// The comment node in question is already part of the DOM structure so we don't need to append
|
|
20216
|
+
// it again.
|
|
20217
|
+
if (hostTNode.type & 8 /* TNodeType.ElementContainer */) {
|
|
20218
|
+
commentNode = unwrapRNode(slotValue);
|
|
20219
|
+
}
|
|
20220
|
+
else {
|
|
20221
|
+
commentNode = insertAnchorNode(hostLView, hostTNode);
|
|
20222
|
+
}
|
|
20223
|
+
lContainer[NATIVE] = commentNode;
|
|
20224
|
+
}
|
|
20225
|
+
/**
|
|
20226
|
+
* Hydration logic that looks up all dehydrated views in this container
|
|
20227
|
+
* and puts them into `lContainer[DEHYDRATED_VIEWS]` slot.
|
|
20228
|
+
*
|
|
20229
|
+
* @returns a boolean flag that indicates whether a populating operation
|
|
20230
|
+
* was successful. The operation might be unsuccessful in case is has completed
|
|
20231
|
+
* previously, we are rendering in client-only mode or this content is located
|
|
20232
|
+
* in a skip hydration section.
|
|
20233
|
+
*/
|
|
20234
|
+
function populateDehydratedViewsInContainerImpl(lContainer, hostLView, hostTNode) {
|
|
20235
|
+
// We already have a native element (anchor) set and the process
|
|
20236
|
+
// of finding dehydrated views happened (so the `lContainer[DEHYDRATED_VIEWS]`
|
|
20237
|
+
// is not null), exit early.
|
|
20238
|
+
if (lContainer[NATIVE] && lContainer[DEHYDRATED_VIEWS]) {
|
|
20239
|
+
return true;
|
|
20240
|
+
}
|
|
20241
|
+
const hydrationInfo = hostLView[HYDRATION];
|
|
20242
|
+
const noOffsetIndex = hostTNode.index - HEADER_OFFSET;
|
|
20243
|
+
// TODO(akushnir): this should really be a single condition, refactor the code
|
|
20244
|
+
// to use `hasInSkipHydrationBlockFlag` logic inside `isInSkipHydrationBlock`.
|
|
20245
|
+
const skipHydration = isInSkipHydrationBlock(hostTNode) || hasInSkipHydrationBlockFlag(hostTNode);
|
|
20246
|
+
const isNodeCreationMode = !hydrationInfo || skipHydration || isDisconnectedNode$1(hydrationInfo, noOffsetIndex);
|
|
20247
|
+
// Regular creation mode.
|
|
20248
|
+
if (isNodeCreationMode) {
|
|
20249
|
+
return false;
|
|
20250
|
+
}
|
|
20251
|
+
// Hydration mode, looking up an anchor node and dehydrated views in DOM.
|
|
20252
|
+
const currentRNode = getSegmentHead(hydrationInfo, noOffsetIndex);
|
|
20253
|
+
const serializedViews = hydrationInfo.data[CONTAINERS]?.[noOffsetIndex];
|
|
20254
|
+
ngDevMode &&
|
|
20255
|
+
assertDefined(serializedViews, 'Unexpected state: no hydration info available for a given TNode, ' +
|
|
20256
|
+
'which represents a view container.');
|
|
20257
|
+
const [commentNode, dehydratedViews] = locateDehydratedViewsInContainer(currentRNode, serializedViews);
|
|
20258
|
+
if (ngDevMode) {
|
|
20259
|
+
validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode, true);
|
|
20260
|
+
// Do not throw in case this node is already claimed (thus `false` as a second
|
|
20261
|
+
// argument). If this container is created based on an `<ng-template>`, the comment
|
|
20262
|
+
// node would be already claimed from the `template` instruction. If an element acts
|
|
20263
|
+
// as an anchor (e.g. <div #vcRef>), a separate comment node would be created/located,
|
|
20264
|
+
// so we need to claim it here.
|
|
20265
|
+
markRNodeAsClaimedByHydration(commentNode, false);
|
|
20266
|
+
}
|
|
20267
|
+
lContainer[NATIVE] = commentNode;
|
|
20268
|
+
lContainer[DEHYDRATED_VIEWS] = dehydratedViews;
|
|
20269
|
+
return true;
|
|
20270
|
+
}
|
|
20271
|
+
function locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
|
|
20272
|
+
if (!_populateDehydratedViewsInContainer(lContainer, hostLView, hostTNode)) {
|
|
20273
|
+
// Populating dehydrated views operation returned `false`, which indicates
|
|
20274
|
+
// that the logic was running in client-only mode, this an anchor comment
|
|
20275
|
+
// node should be created for this container.
|
|
20276
|
+
createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
|
|
20277
|
+
}
|
|
20278
|
+
}
|
|
20279
|
+
function enableLocateOrCreateContainerRefImpl() {
|
|
20280
|
+
_locateOrCreateAnchorNode = locateOrCreateAnchorNode;
|
|
20281
|
+
_populateDehydratedViewsInContainer = populateDehydratedViewsInContainerImpl;
|
|
20282
|
+
}
|
|
20283
|
+
|
|
20284
|
+
const DEFER_BLOCK_STATE = 0;
|
|
20285
|
+
|
|
20286
|
+
/**
|
|
20287
|
+
* Returns whether defer blocks should be triggered.
|
|
20288
|
+
*
|
|
20289
|
+
* Currently, defer blocks are not triggered on the server,
|
|
20290
|
+
* only placeholder content is rendered (if provided).
|
|
20291
|
+
*/
|
|
20292
|
+
function shouldTriggerDeferBlock(injector) {
|
|
20293
|
+
return isPlatformBrowser(injector);
|
|
20294
|
+
}
|
|
20295
|
+
/**
|
|
20296
|
+
* Shims for the `requestIdleCallback` and `cancelIdleCallback` functions for environments
|
|
20297
|
+
* where those functions are not available (e.g. Node.js).
|
|
20298
|
+
*/
|
|
20299
|
+
const _requestIdleCallback = typeof requestIdleCallback !== 'undefined' ? requestIdleCallback : setTimeout;
|
|
20300
|
+
const _cancelIdleCallback = typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback : clearTimeout;
|
|
20301
|
+
/**
|
|
20302
|
+
* Creates runtime data structures for `{#defer}` blocks.
|
|
20303
|
+
*
|
|
20304
|
+
* @param index Index of the `defer` instruction.
|
|
20305
|
+
* @param primaryTmplIndex Index of the template with the primary block content.
|
|
20306
|
+
* @param dependencyResolverFn Function that contains dependencies for this defer block.
|
|
20307
|
+
* @param loadingTmplIndex Index of the template with the `{:loading}` block content.
|
|
20308
|
+
* @param placeholderTmplIndex Index of the template with the `{:placeholder}` block content.
|
|
20309
|
+
* @param errorTmplIndex Index of the template with the `{:error}` block content.
|
|
20310
|
+
* @param loadingConfigIndex Index in the constants array of the configuration of the `{:loading}`.
|
|
20311
|
+
* block.
|
|
20312
|
+
* @param placeholderConfigIndexIndex in the constants array of the configuration of the
|
|
20313
|
+
* `{:placeholder}` block.
|
|
20314
|
+
*
|
|
20315
|
+
* @codeGenApi
|
|
20316
|
+
*/
|
|
20317
|
+
function ɵɵdefer(index, primaryTmplIndex, dependencyResolverFn, loadingTmplIndex, placeholderTmplIndex, errorTmplIndex, loadingConfigIndex, placeholderConfigIndex) {
|
|
20318
|
+
const lView = getLView();
|
|
20319
|
+
const tView = getTView();
|
|
20320
|
+
const tViewConsts = tView.consts;
|
|
20321
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
20322
|
+
ɵɵtemplate(index, null, 0, 0);
|
|
20323
|
+
if (tView.firstCreatePass) {
|
|
20324
|
+
const deferBlockConfig = {
|
|
20325
|
+
primaryTmplIndex,
|
|
20326
|
+
loadingTmplIndex: loadingTmplIndex ?? null,
|
|
20327
|
+
placeholderTmplIndex: placeholderTmplIndex ?? null,
|
|
20328
|
+
errorTmplIndex: errorTmplIndex ?? null,
|
|
20329
|
+
placeholderBlockConfig: placeholderConfigIndex != null ?
|
|
20330
|
+
getConstant(tViewConsts, placeholderConfigIndex) :
|
|
20331
|
+
null,
|
|
20332
|
+
loadingBlockConfig: loadingConfigIndex != null ?
|
|
20333
|
+
getConstant(tViewConsts, loadingConfigIndex) :
|
|
20334
|
+
null,
|
|
20335
|
+
dependencyResolverFn: dependencyResolverFn ?? null,
|
|
20336
|
+
loadingState: 0 /* DeferDependenciesLoadingState.NOT_STARTED */,
|
|
20337
|
+
loadingPromise: null,
|
|
20338
|
+
};
|
|
20339
|
+
setTDeferBlockDetails(tView, adjustedIndex, deferBlockConfig);
|
|
20340
|
+
}
|
|
20341
|
+
// Lookup dehydrated views that belong to this LContainer.
|
|
20342
|
+
// In client-only mode, this operation is noop.
|
|
20343
|
+
const lContainer = lView[adjustedIndex];
|
|
20344
|
+
populateDehydratedViewsInContainer(lContainer);
|
|
20345
|
+
// Init instance-specific defer details and store it.
|
|
20346
|
+
const lDetails = [];
|
|
20347
|
+
lDetails[DEFER_BLOCK_STATE] = 0 /* DeferBlockInstanceState.INITIAL */;
|
|
20348
|
+
setLDeferBlockDetails(lView, adjustedIndex, lDetails);
|
|
20349
|
+
}
|
|
20350
|
+
/**
|
|
20351
|
+
* Loads defer block dependencies when a trigger value becomes truthy.
|
|
20352
|
+
* @codeGenApi
|
|
20353
|
+
*/
|
|
20354
|
+
function ɵɵdeferWhen(rawValue) {
|
|
20355
|
+
const lView = getLView();
|
|
20356
|
+
const bindingIndex = nextBindingIndex();
|
|
20357
|
+
if (bindingUpdated(lView, bindingIndex, rawValue)) {
|
|
20358
|
+
const value = Boolean(rawValue); // handle truthy or falsy values
|
|
20359
|
+
const tNode = getSelectedTNode();
|
|
20360
|
+
const lDetails = getLDeferBlockDetails(lView, tNode);
|
|
20361
|
+
const renderedState = lDetails[DEFER_BLOCK_STATE];
|
|
20362
|
+
if (value === false && renderedState === 0 /* DeferBlockInstanceState.INITIAL */) {
|
|
20363
|
+
// If nothing is rendered yet, render a placeholder (if defined).
|
|
20364
|
+
renderPlaceholder(lView, tNode);
|
|
20365
|
+
}
|
|
20366
|
+
else if (value === true &&
|
|
20367
|
+
(renderedState === 0 /* DeferBlockInstanceState.INITIAL */ ||
|
|
20368
|
+
renderedState === 1 /* DeferBlockInstanceState.PLACEHOLDER */)) {
|
|
20369
|
+
// The `when` condition has changed to `true`, trigger defer block loading
|
|
20370
|
+
// if the block is either in initial (nothing is rendered) or a placeholder
|
|
20371
|
+
// state.
|
|
20372
|
+
triggerDeferBlock(lView, tNode);
|
|
20373
|
+
}
|
|
20374
|
+
}
|
|
20375
|
+
}
|
|
20376
|
+
/**
|
|
20377
|
+
* Prefetches the deferred content when a value becomes truthy.
|
|
20378
|
+
* @codeGenApi
|
|
20379
|
+
*/
|
|
20380
|
+
function ɵɵdeferPrefetchWhen(rawValue) {
|
|
20381
|
+
const lView = getLView();
|
|
20382
|
+
const bindingIndex = nextBindingIndex();
|
|
20383
|
+
if (bindingUpdated(lView, bindingIndex, rawValue)) {
|
|
20384
|
+
const value = Boolean(rawValue); // handle truthy or falsy values
|
|
20385
|
+
const tView = lView[TVIEW];
|
|
20386
|
+
const tNode = getSelectedTNode();
|
|
20387
|
+
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
20388
|
+
if (value === true && tDetails.loadingState === 0 /* DeferDependenciesLoadingState.NOT_STARTED */) {
|
|
20389
|
+
// If loading has not been started yet, trigger it now.
|
|
20390
|
+
triggerResourceLoading(tDetails, tView, lView);
|
|
20391
|
+
}
|
|
20392
|
+
}
|
|
20393
|
+
}
|
|
20394
|
+
/**
|
|
20395
|
+
* Sets up handlers that represent `on idle` deferred trigger.
|
|
20396
|
+
* @codeGenApi
|
|
20397
|
+
*/
|
|
20398
|
+
function ɵɵdeferOnIdle() {
|
|
20399
|
+
const lView = getLView();
|
|
20400
|
+
const tNode = getCurrentTNode();
|
|
20401
|
+
renderPlaceholder(lView, tNode);
|
|
20402
|
+
// Note: we pass an `lView` as a second argument to cancel an `idle`
|
|
20403
|
+
// callback in case an LView got destroyed before an `idle` callback
|
|
20404
|
+
// is invoked.
|
|
20405
|
+
onIdle(() => triggerDeferBlock(lView, tNode), lView);
|
|
20406
|
+
}
|
|
20407
|
+
/**
|
|
20408
|
+
* Creates runtime data structures for the `prefetch on idle` deferred trigger.
|
|
20409
|
+
* @codeGenApi
|
|
20410
|
+
*/
|
|
20411
|
+
function ɵɵdeferPrefetchOnIdle() {
|
|
20412
|
+
const lView = getLView();
|
|
20413
|
+
const tNode = getCurrentTNode();
|
|
20414
|
+
const tView = lView[TVIEW];
|
|
20415
|
+
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
20416
|
+
if (tDetails.loadingState === 0 /* DeferDependenciesLoadingState.NOT_STARTED */) {
|
|
20417
|
+
// Set loading to the scheduled state, so that we don't register it again.
|
|
20418
|
+
tDetails.loadingState = 1 /* DeferDependenciesLoadingState.SCHEDULED */;
|
|
20419
|
+
// In case of prefetching, we intentionally avoid cancelling prefetching if
|
|
20420
|
+
// an underlying LView get destroyed (thus passing `null` as a second argument),
|
|
20421
|
+
// because there might be other LViews (that represent embedded views) that
|
|
20422
|
+
// depend on resource loading.
|
|
20423
|
+
onIdle(() => triggerResourceLoading(tDetails, tView, lView), null /* LView */);
|
|
20424
|
+
}
|
|
20425
|
+
}
|
|
20426
|
+
/**
|
|
20427
|
+
* Creates runtime data structures for the `on immediate` deferred trigger.
|
|
20428
|
+
* @codeGenApi
|
|
20429
|
+
*/
|
|
20430
|
+
function ɵɵdeferOnImmediate() { } // TODO: implement runtime logic.
|
|
20431
|
+
/**
|
|
20432
|
+
* Creates runtime data structures for the `prefetch on immediate` deferred trigger.
|
|
20433
|
+
* @codeGenApi
|
|
20434
|
+
*/
|
|
20435
|
+
function ɵɵdeferPrefetchOnImmediate() { } // TODO: implement runtime logic.
|
|
20436
|
+
/**
|
|
20437
|
+
* Creates runtime data structures for the `on timer` deferred trigger.
|
|
19794
20438
|
* @param delay Amount of time to wait before loading the content.
|
|
19795
20439
|
* @codeGenApi
|
|
19796
20440
|
*/
|
|
@@ -19836,6 +20480,35 @@ function ɵɵdeferOnViewport(target) { } // TODO: implement runtime logic.
|
|
|
19836
20480
|
*/
|
|
19837
20481
|
function ɵɵdeferPrefetchOnViewport(target) { } // TODO: implement runtime logic.
|
|
19838
20482
|
/********** Helper functions **********/
|
|
20483
|
+
/**
|
|
20484
|
+
* Helper function to schedule a callback to be invoked when a browser becomes idle.
|
|
20485
|
+
*
|
|
20486
|
+
* @param callback A function to be invoked when a browser becomes idle.
|
|
20487
|
+
* @param lView An optional LView that hosts an instance of a defer block. LView is
|
|
20488
|
+
* used to register a cleanup callback in case that LView got destroyed before
|
|
20489
|
+
* callback was invoked. In this case, an `idle` callback is never invoked. This is
|
|
20490
|
+
* helpful for cases when a defer block has scheduled rendering, but an underlying
|
|
20491
|
+
* LView got destroyed prior to th block rendering.
|
|
20492
|
+
*/
|
|
20493
|
+
function onIdle(callback, lView) {
|
|
20494
|
+
let id;
|
|
20495
|
+
const removeIdleCallback = () => _cancelIdleCallback(id);
|
|
20496
|
+
id = _requestIdleCallback(() => {
|
|
20497
|
+
removeIdleCallback();
|
|
20498
|
+
if (lView !== null) {
|
|
20499
|
+
// The idle callback is invoked, we no longer need
|
|
20500
|
+
// to retain a cleanup callback in an LView.
|
|
20501
|
+
removeLViewOnDestroy(lView, removeIdleCallback);
|
|
20502
|
+
}
|
|
20503
|
+
callback();
|
|
20504
|
+
});
|
|
20505
|
+
if (lView !== null) {
|
|
20506
|
+
// Store a cleanup function on LView, so that we cancel idle
|
|
20507
|
+
// callback in case this LView is destroyed before a callback
|
|
20508
|
+
// is invoked.
|
|
20509
|
+
storeLViewOnDestroy(lView, removeIdleCallback);
|
|
20510
|
+
}
|
|
20511
|
+
}
|
|
19839
20512
|
/**
|
|
19840
20513
|
* Calculates a data slot index for defer block info (either static or
|
|
19841
20514
|
* instance-specific), given an index of a defer instruction.
|
|
@@ -19903,27 +20576,31 @@ function renderDeferBlockState(newState, tNode, lContainer, stateTmplIndex) {
|
|
|
19903
20576
|
// represents a `{#defer}` block, so always refer to the first one.
|
|
19904
20577
|
const viewIndex = 0;
|
|
19905
20578
|
removeLViewFromLContainer(lContainer, viewIndex);
|
|
19906
|
-
const
|
|
19907
|
-
|
|
20579
|
+
const dehydratedView = findMatchingDehydratedView(lContainer, tNode.tView.ssrId);
|
|
20580
|
+
const embeddedLView = createAndRenderEmbeddedLView(hostLView, tNode, null, { dehydratedView });
|
|
20581
|
+
addLViewToLContainer(lContainer, embeddedLView, viewIndex, shouldAddViewToDom(tNode, dehydratedView));
|
|
19908
20582
|
}
|
|
19909
20583
|
}
|
|
19910
20584
|
/**
|
|
19911
20585
|
* Trigger loading of defer block dependencies if the process hasn't started yet.
|
|
19912
20586
|
*
|
|
19913
20587
|
* @param tDetails Static information about this defer block.
|
|
19914
|
-
* @param
|
|
19915
|
-
* @param
|
|
20588
|
+
* @param tView TView of a host view.
|
|
20589
|
+
* @param lView LView of a host view.
|
|
19916
20590
|
*/
|
|
19917
|
-
function triggerResourceLoading(tDetails,
|
|
19918
|
-
const
|
|
19919
|
-
if (
|
|
20591
|
+
function triggerResourceLoading(tDetails, tView, lView) {
|
|
20592
|
+
const injector = lView[INJECTOR$1];
|
|
20593
|
+
if (!shouldTriggerDeferBlock(injector) ||
|
|
20594
|
+
(tDetails.loadingState !== 0 /* DeferDependenciesLoadingState.NOT_STARTED */ &&
|
|
20595
|
+
tDetails.loadingState !== 1 /* DeferDependenciesLoadingState.SCHEDULED */)) {
|
|
19920
20596
|
// If the loading status is different from initial one, it means that
|
|
19921
20597
|
// the loading of dependencies is in progress and there is nothing to do
|
|
19922
20598
|
// in this function. All details can be obtained from the `tDetails` object.
|
|
19923
20599
|
return;
|
|
19924
20600
|
}
|
|
20601
|
+
const primaryBlockTNode = getPrimaryBlockTNode(tView, tDetails);
|
|
19925
20602
|
// Switch from NOT_STARTED -> IN_PROGRESS state.
|
|
19926
|
-
tDetails.loadingState =
|
|
20603
|
+
tDetails.loadingState = 2 /* DeferDependenciesLoadingState.IN_PROGRESS */;
|
|
19927
20604
|
// Check if dependency function interceptor is configured.
|
|
19928
20605
|
const deferDependencyInterceptor = injector.get(DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, null, { optional: true });
|
|
19929
20606
|
const dependenciesFn = deferDependencyInterceptor ?
|
|
@@ -19934,7 +20611,7 @@ function triggerResourceLoading(tDetails, primaryBlockTNode, injector) {
|
|
|
19934
20611
|
// thus no dynamic `import()`s were produced.
|
|
19935
20612
|
if (!dependenciesFn) {
|
|
19936
20613
|
tDetails.loadingPromise = Promise.resolve().then(() => {
|
|
19937
|
-
tDetails.loadingState =
|
|
20614
|
+
tDetails.loadingState = 3 /* DeferDependenciesLoadingState.COMPLETE */;
|
|
19938
20615
|
});
|
|
19939
20616
|
return;
|
|
19940
20617
|
}
|
|
@@ -19965,18 +20642,21 @@ function triggerResourceLoading(tDetails, primaryBlockTNode, injector) {
|
|
|
19965
20642
|
// Loading is completed, we no longer need this Promise.
|
|
19966
20643
|
tDetails.loadingPromise = null;
|
|
19967
20644
|
if (failed) {
|
|
19968
|
-
tDetails.loadingState =
|
|
20645
|
+
tDetails.loadingState = 4 /* DeferDependenciesLoadingState.FAILED */;
|
|
19969
20646
|
}
|
|
19970
20647
|
else {
|
|
19971
|
-
tDetails.loadingState =
|
|
20648
|
+
tDetails.loadingState = 3 /* DeferDependenciesLoadingState.COMPLETE */;
|
|
19972
20649
|
// Update directive and pipe registries to add newly downloaded dependencies.
|
|
20650
|
+
const primaryBlockTView = primaryBlockTNode.tView;
|
|
19973
20651
|
if (directiveDefs.length > 0) {
|
|
19974
|
-
|
|
19975
|
-
[...
|
|
20652
|
+
primaryBlockTView.directiveRegistry = primaryBlockTView.directiveRegistry ?
|
|
20653
|
+
[...primaryBlockTView.directiveRegistry, ...directiveDefs] :
|
|
19976
20654
|
directiveDefs;
|
|
19977
20655
|
}
|
|
19978
20656
|
if (pipeDefs.length > 0) {
|
|
19979
|
-
|
|
20657
|
+
primaryBlockTView.pipeRegistry = primaryBlockTView.pipeRegistry ?
|
|
20658
|
+
[...primaryBlockTView.pipeRegistry, ...pipeDefs] :
|
|
20659
|
+
pipeDefs;
|
|
19980
20660
|
}
|
|
19981
20661
|
}
|
|
19982
20662
|
});
|
|
@@ -20000,12 +20680,12 @@ function renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer) {
|
|
|
20000
20680
|
ngDevMode &&
|
|
20001
20681
|
assertDefined(tDetails.loadingPromise, 'Expected loading Promise to exist on this defer block');
|
|
20002
20682
|
tDetails.loadingPromise.then(() => {
|
|
20003
|
-
if (tDetails.loadingState ===
|
|
20683
|
+
if (tDetails.loadingState === 3 /* DeferDependenciesLoadingState.COMPLETE */) {
|
|
20004
20684
|
ngDevMode && assertDeferredDependenciesLoaded(tDetails);
|
|
20005
20685
|
// Everything is loaded, show the primary block content
|
|
20006
20686
|
renderDeferBlockState(3 /* DeferBlockInstanceState.COMPLETE */, tNode, lContainer, tDetails.primaryTmplIndex);
|
|
20007
20687
|
}
|
|
20008
|
-
else if (tDetails.loadingState ===
|
|
20688
|
+
else if (tDetails.loadingState === 4 /* DeferDependenciesLoadingState.FAILED */) {
|
|
20009
20689
|
renderDeferBlockState(4 /* DeferBlockInstanceState.ERROR */, tNode, lContainer, tDetails.errorTmplIndex);
|
|
20010
20690
|
}
|
|
20011
20691
|
});
|
|
@@ -20023,28 +20703,32 @@ function getPrimaryBlockTNode(tView, tDetails) {
|
|
|
20023
20703
|
function triggerDeferBlock(lView, tNode) {
|
|
20024
20704
|
const tView = lView[TVIEW];
|
|
20025
20705
|
const lContainer = lView[tNode.index];
|
|
20706
|
+
const injector = lView[INJECTOR$1];
|
|
20026
20707
|
ngDevMode && assertLContainer(lContainer);
|
|
20708
|
+
if (!shouldTriggerDeferBlock(injector))
|
|
20709
|
+
return;
|
|
20027
20710
|
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
20028
20711
|
// Condition is triggered, try to render loading state and start downloading.
|
|
20029
20712
|
// Note: if a block is in a loading, completed or an error state, this call would be a noop.
|
|
20030
20713
|
renderDeferBlockState(2 /* DeferBlockInstanceState.LOADING */, tNode, lContainer, tDetails.loadingTmplIndex);
|
|
20031
20714
|
switch (tDetails.loadingState) {
|
|
20032
20715
|
case 0 /* DeferDependenciesLoadingState.NOT_STARTED */:
|
|
20033
|
-
|
|
20716
|
+
case 1 /* DeferDependenciesLoadingState.SCHEDULED */:
|
|
20717
|
+
triggerResourceLoading(tDetails, lView[TVIEW], lView);
|
|
20034
20718
|
// The `loadingState` might have changed to "loading".
|
|
20035
20719
|
if (tDetails.loadingState ===
|
|
20036
|
-
|
|
20720
|
+
2 /* DeferDependenciesLoadingState.IN_PROGRESS */) {
|
|
20037
20721
|
renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer);
|
|
20038
20722
|
}
|
|
20039
20723
|
break;
|
|
20040
|
-
case
|
|
20724
|
+
case 2 /* DeferDependenciesLoadingState.IN_PROGRESS */:
|
|
20041
20725
|
renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer);
|
|
20042
20726
|
break;
|
|
20043
|
-
case
|
|
20727
|
+
case 3 /* DeferDependenciesLoadingState.COMPLETE */:
|
|
20044
20728
|
ngDevMode && assertDeferredDependenciesLoaded(tDetails);
|
|
20045
20729
|
renderDeferBlockState(3 /* DeferBlockInstanceState.COMPLETE */, tNode, lContainer, tDetails.primaryTmplIndex);
|
|
20046
20730
|
break;
|
|
20047
|
-
case
|
|
20731
|
+
case 4 /* DeferDependenciesLoadingState.FAILED */:
|
|
20048
20732
|
renderDeferBlockState(4 /* DeferBlockInstanceState.ERROR */, tNode, lContainer, tDetails.errorTmplIndex);
|
|
20049
20733
|
break;
|
|
20050
20734
|
default:
|
|
@@ -20059,7 +20743,7 @@ function triggerDeferBlock(lView, tNode) {
|
|
|
20059
20743
|
* block in completed state.
|
|
20060
20744
|
*/
|
|
20061
20745
|
function assertDeferredDependenciesLoaded(tDetails) {
|
|
20062
|
-
assertEqual(tDetails.loadingState,
|
|
20746
|
+
assertEqual(tDetails.loadingState, 3 /* DeferDependenciesLoadingState.COMPLETE */, 'Expecting all deferred dependencies to be loaded.');
|
|
20063
20747
|
}
|
|
20064
20748
|
/**
|
|
20065
20749
|
* **INTERNAL**, avoid referencing it in application code.
|
|
@@ -25363,265 +26047,55 @@ function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
|
|
|
25363
26047
|
* If the value hasn't been saved, calls the pure function to store and return the
|
|
25364
26048
|
* value. If it has been saved, returns the saved value.
|
|
25365
26049
|
*
|
|
25366
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25367
|
-
* @param pureFn Function that returns a value
|
|
25368
|
-
* @param thisArg Optional calling context of pureFn
|
|
25369
|
-
* @returns value
|
|
25370
|
-
*
|
|
25371
|
-
* @codeGenApi
|
|
25372
|
-
*/
|
|
25373
|
-
function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
|
|
25374
|
-
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25375
|
-
const lView = getLView();
|
|
25376
|
-
return lView[bindingIndex] === NO_CHANGE ?
|
|
25377
|
-
updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
|
|
25378
|
-
getBinding(lView, bindingIndex);
|
|
25379
|
-
}
|
|
25380
|
-
/**
|
|
25381
|
-
* If the value of the provided exp has changed, calls the pure function to return
|
|
25382
|
-
* an updated value. Or if the value has not changed, returns cached value.
|
|
25383
|
-
*
|
|
25384
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25385
|
-
* @param pureFn Function that returns an updated value
|
|
25386
|
-
* @param exp Updated expression value
|
|
25387
|
-
* @param thisArg Optional calling context of pureFn
|
|
25388
|
-
* @returns Updated or cached value
|
|
25389
|
-
*
|
|
25390
|
-
* @codeGenApi
|
|
25391
|
-
*/
|
|
25392
|
-
function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
|
|
25393
|
-
return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
|
|
25394
|
-
}
|
|
25395
|
-
/**
|
|
25396
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25397
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25398
|
-
*
|
|
25399
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25400
|
-
* @param pureFn
|
|
25401
|
-
* @param exp1
|
|
25402
|
-
* @param exp2
|
|
25403
|
-
* @param thisArg Optional calling context of pureFn
|
|
25404
|
-
* @returns Updated or cached value
|
|
25405
|
-
*
|
|
25406
|
-
* @codeGenApi
|
|
25407
|
-
*/
|
|
25408
|
-
function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
|
|
25409
|
-
return pureFunction2Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
|
|
25410
|
-
}
|
|
25411
|
-
/**
|
|
25412
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25413
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25414
|
-
*
|
|
25415
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25416
|
-
* @param pureFn
|
|
25417
|
-
* @param exp1
|
|
25418
|
-
* @param exp2
|
|
25419
|
-
* @param exp3
|
|
25420
|
-
* @param thisArg Optional calling context of pureFn
|
|
25421
|
-
* @returns Updated or cached value
|
|
25422
|
-
*
|
|
25423
|
-
* @codeGenApi
|
|
25424
|
-
*/
|
|
25425
|
-
function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
|
|
25426
|
-
return pureFunction3Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
|
|
25427
|
-
}
|
|
25428
|
-
/**
|
|
25429
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25430
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25431
|
-
*
|
|
25432
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25433
|
-
* @param pureFn
|
|
25434
|
-
* @param exp1
|
|
25435
|
-
* @param exp2
|
|
25436
|
-
* @param exp3
|
|
25437
|
-
* @param exp4
|
|
25438
|
-
* @param thisArg Optional calling context of pureFn
|
|
25439
|
-
* @returns Updated or cached value
|
|
25440
|
-
*
|
|
25441
|
-
* @codeGenApi
|
|
25442
|
-
*/
|
|
25443
|
-
function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
|
|
25444
|
-
return pureFunction4Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
|
|
25445
|
-
}
|
|
25446
|
-
/**
|
|
25447
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25448
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25449
|
-
*
|
|
25450
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25451
|
-
* @param pureFn
|
|
25452
|
-
* @param exp1
|
|
25453
|
-
* @param exp2
|
|
25454
|
-
* @param exp3
|
|
25455
|
-
* @param exp4
|
|
25456
|
-
* @param exp5
|
|
25457
|
-
* @param thisArg Optional calling context of pureFn
|
|
25458
|
-
* @returns Updated or cached value
|
|
25459
|
-
*
|
|
25460
|
-
* @codeGenApi
|
|
25461
|
-
*/
|
|
25462
|
-
function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
|
|
25463
|
-
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25464
|
-
const lView = getLView();
|
|
25465
|
-
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
25466
|
-
return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
|
|
25467
|
-
updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
|
|
25468
|
-
pureFn(exp1, exp2, exp3, exp4, exp5)) :
|
|
25469
|
-
getBinding(lView, bindingIndex + 5);
|
|
25470
|
-
}
|
|
25471
|
-
/**
|
|
25472
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25473
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25474
|
-
*
|
|
25475
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25476
|
-
* @param pureFn
|
|
25477
|
-
* @param exp1
|
|
25478
|
-
* @param exp2
|
|
25479
|
-
* @param exp3
|
|
25480
|
-
* @param exp4
|
|
25481
|
-
* @param exp5
|
|
25482
|
-
* @param exp6
|
|
25483
|
-
* @param thisArg Optional calling context of pureFn
|
|
25484
|
-
* @returns Updated or cached value
|
|
25485
|
-
*
|
|
25486
|
-
* @codeGenApi
|
|
25487
|
-
*/
|
|
25488
|
-
function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
|
|
25489
|
-
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25490
|
-
const lView = getLView();
|
|
25491
|
-
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
25492
|
-
return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
|
|
25493
|
-
updateBinding(lView, bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
|
|
25494
|
-
pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
|
|
25495
|
-
getBinding(lView, bindingIndex + 6);
|
|
25496
|
-
}
|
|
25497
|
-
/**
|
|
25498
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25499
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25500
|
-
*
|
|
25501
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25502
|
-
* @param pureFn
|
|
25503
|
-
* @param exp1
|
|
25504
|
-
* @param exp2
|
|
25505
|
-
* @param exp3
|
|
25506
|
-
* @param exp4
|
|
25507
|
-
* @param exp5
|
|
25508
|
-
* @param exp6
|
|
25509
|
-
* @param exp7
|
|
25510
|
-
* @param thisArg Optional calling context of pureFn
|
|
25511
|
-
* @returns Updated or cached value
|
|
25512
|
-
*
|
|
25513
|
-
* @codeGenApi
|
|
25514
|
-
*/
|
|
25515
|
-
function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
|
|
25516
|
-
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25517
|
-
const lView = getLView();
|
|
25518
|
-
let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
25519
|
-
return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
|
|
25520
|
-
updateBinding(lView, bindingIndex + 7, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
|
|
25521
|
-
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
|
|
25522
|
-
getBinding(lView, bindingIndex + 7);
|
|
25523
|
-
}
|
|
25524
|
-
/**
|
|
25525
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25526
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25527
|
-
*
|
|
25528
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25529
|
-
* @param pureFn
|
|
25530
|
-
* @param exp1
|
|
25531
|
-
* @param exp2
|
|
25532
|
-
* @param exp3
|
|
25533
|
-
* @param exp4
|
|
25534
|
-
* @param exp5
|
|
25535
|
-
* @param exp6
|
|
25536
|
-
* @param exp7
|
|
25537
|
-
* @param exp8
|
|
25538
|
-
* @param thisArg Optional calling context of pureFn
|
|
25539
|
-
* @returns Updated or cached value
|
|
25540
|
-
*
|
|
25541
|
-
* @codeGenApi
|
|
25542
|
-
*/
|
|
25543
|
-
function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
|
|
25544
|
-
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25545
|
-
const lView = getLView();
|
|
25546
|
-
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
25547
|
-
return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
|
|
25548
|
-
updateBinding(lView, bindingIndex + 8, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
|
|
25549
|
-
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
|
|
25550
|
-
getBinding(lView, bindingIndex + 8);
|
|
25551
|
-
}
|
|
25552
|
-
/**
|
|
25553
|
-
* pureFunction instruction that can support any number of bindings.
|
|
25554
|
-
*
|
|
25555
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25556
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25557
|
-
*
|
|
25558
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25559
|
-
* @param pureFn A pure function that takes binding values and builds an object or array
|
|
25560
|
-
* containing those values.
|
|
25561
|
-
* @param exps An array of binding values
|
|
26050
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26051
|
+
* @param pureFn Function that returns a value
|
|
25562
26052
|
* @param thisArg Optional calling context of pureFn
|
|
25563
|
-
* @returns
|
|
26053
|
+
* @returns value
|
|
25564
26054
|
*
|
|
25565
26055
|
* @codeGenApi
|
|
25566
26056
|
*/
|
|
25567
|
-
function
|
|
25568
|
-
|
|
25569
|
-
|
|
25570
|
-
|
|
25571
|
-
|
|
25572
|
-
|
|
25573
|
-
* invocation and not produce any valid results. In this case LView would keep holding the NO_CHANGE
|
|
25574
|
-
* value. The NO_CHANGE is not something that we can use in expressions / bindings thus we convert
|
|
25575
|
-
* it to `undefined`.
|
|
25576
|
-
*/
|
|
25577
|
-
function getPureFunctionReturnValue(lView, returnValueIndex) {
|
|
25578
|
-
ngDevMode && assertIndexInRange(lView, returnValueIndex);
|
|
25579
|
-
const lastReturnValue = lView[returnValueIndex];
|
|
25580
|
-
return lastReturnValue === NO_CHANGE ? undefined : lastReturnValue;
|
|
26057
|
+
function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
|
|
26058
|
+
const bindingIndex = getBindingRoot() + slotOffset;
|
|
26059
|
+
const lView = getLView();
|
|
26060
|
+
return lView[bindingIndex] === NO_CHANGE ?
|
|
26061
|
+
updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
|
|
26062
|
+
getBinding(lView, bindingIndex);
|
|
25581
26063
|
}
|
|
25582
26064
|
/**
|
|
25583
26065
|
* If the value of the provided exp has changed, calls the pure function to return
|
|
25584
26066
|
* an updated value. Or if the value has not changed, returns cached value.
|
|
25585
26067
|
*
|
|
25586
|
-
* @param lView LView in which the function is being executed.
|
|
25587
|
-
* @param bindingRoot Binding root index.
|
|
25588
26068
|
* @param slotOffset the offset from binding root to the reserved slot
|
|
25589
26069
|
* @param pureFn Function that returns an updated value
|
|
25590
26070
|
* @param exp Updated expression value
|
|
25591
26071
|
* @param thisArg Optional calling context of pureFn
|
|
25592
26072
|
* @returns Updated or cached value
|
|
26073
|
+
*
|
|
26074
|
+
* @codeGenApi
|
|
25593
26075
|
*/
|
|
25594
|
-
function
|
|
25595
|
-
|
|
25596
|
-
return bindingUpdated(lView, bindingIndex, exp) ?
|
|
25597
|
-
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
|
|
25598
|
-
getPureFunctionReturnValue(lView, bindingIndex + 1);
|
|
26076
|
+
function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
|
|
26077
|
+
return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
|
|
25599
26078
|
}
|
|
25600
26079
|
/**
|
|
25601
26080
|
* If the value of any provided exp has changed, calls the pure function to return
|
|
25602
26081
|
* an updated value. Or if no values have changed, returns cached value.
|
|
25603
26082
|
*
|
|
25604
|
-
* @param lView LView in which the function is being executed.
|
|
25605
|
-
* @param bindingRoot Binding root index.
|
|
25606
26083
|
* @param slotOffset the offset from binding root to the reserved slot
|
|
25607
26084
|
* @param pureFn
|
|
25608
26085
|
* @param exp1
|
|
25609
26086
|
* @param exp2
|
|
25610
26087
|
* @param thisArg Optional calling context of pureFn
|
|
25611
26088
|
* @returns Updated or cached value
|
|
26089
|
+
*
|
|
26090
|
+
* @codeGenApi
|
|
25612
26091
|
*/
|
|
25613
|
-
function
|
|
25614
|
-
|
|
25615
|
-
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
|
|
25616
|
-
updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
|
|
25617
|
-
getPureFunctionReturnValue(lView, bindingIndex + 2);
|
|
26092
|
+
function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
|
|
26093
|
+
return pureFunction2Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
|
|
25618
26094
|
}
|
|
25619
26095
|
/**
|
|
25620
26096
|
* If the value of any provided exp has changed, calls the pure function to return
|
|
25621
26097
|
* an updated value. Or if no values have changed, returns cached value.
|
|
25622
26098
|
*
|
|
25623
|
-
* @param lView LView in which the function is being executed.
|
|
25624
|
-
* @param bindingRoot Binding root index.
|
|
25625
26099
|
* @param slotOffset the offset from binding root to the reserved slot
|
|
25626
26100
|
* @param pureFn
|
|
25627
26101
|
* @param exp1
|
|
@@ -25629,19 +26103,16 @@ function pureFunction2Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp
|
|
|
25629
26103
|
* @param exp3
|
|
25630
26104
|
* @param thisArg Optional calling context of pureFn
|
|
25631
26105
|
* @returns Updated or cached value
|
|
26106
|
+
*
|
|
26107
|
+
* @codeGenApi
|
|
25632
26108
|
*/
|
|
25633
|
-
function
|
|
25634
|
-
|
|
25635
|
-
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
|
|
25636
|
-
updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
|
|
25637
|
-
getPureFunctionReturnValue(lView, bindingIndex + 3);
|
|
26109
|
+
function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
|
|
26110
|
+
return pureFunction3Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
|
|
25638
26111
|
}
|
|
25639
26112
|
/**
|
|
25640
26113
|
* If the value of any provided exp has changed, calls the pure function to return
|
|
25641
26114
|
* an updated value. Or if no values have changed, returns cached value.
|
|
25642
26115
|
*
|
|
25643
|
-
* @param lView LView in which the function is being executed.
|
|
25644
|
-
* @param bindingRoot Binding root index.
|
|
25645
26116
|
* @param slotOffset the offset from binding root to the reserved slot
|
|
25646
26117
|
* @param pureFn
|
|
25647
26118
|
* @param exp1
|
|
@@ -25651,1017 +26122,704 @@ function pureFunction3Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp
|
|
|
25651
26122
|
* @param thisArg Optional calling context of pureFn
|
|
25652
26123
|
* @returns Updated or cached value
|
|
25653
26124
|
*
|
|
25654
|
-
*/
|
|
25655
|
-
function pureFunction4Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
|
|
25656
|
-
const bindingIndex = bindingRoot + slotOffset;
|
|
25657
|
-
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
|
|
25658
|
-
updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
|
|
25659
|
-
getPureFunctionReturnValue(lView, bindingIndex + 4);
|
|
25660
|
-
}
|
|
25661
|
-
/**
|
|
25662
|
-
* pureFunction instruction that can support any number of bindings.
|
|
25663
|
-
*
|
|
25664
|
-
* If the value of any provided exp has changed, calls the pure function to return
|
|
25665
|
-
* an updated value. Or if no values have changed, returns cached value.
|
|
25666
|
-
*
|
|
25667
|
-
* @param lView LView in which the function is being executed.
|
|
25668
|
-
* @param bindingRoot Binding root index.
|
|
25669
|
-
* @param slotOffset the offset from binding root to the reserved slot
|
|
25670
|
-
* @param pureFn A pure function that takes binding values and builds an object or array
|
|
25671
|
-
* containing those values.
|
|
25672
|
-
* @param exps An array of binding values
|
|
25673
|
-
* @param thisArg Optional calling context of pureFn
|
|
25674
|
-
* @returns Updated or cached value
|
|
25675
|
-
*/
|
|
25676
|
-
function pureFunctionVInternal(lView, bindingRoot, slotOffset, pureFn, exps, thisArg) {
|
|
25677
|
-
let bindingIndex = bindingRoot + slotOffset;
|
|
25678
|
-
let different = false;
|
|
25679
|
-
for (let i = 0; i < exps.length; i++) {
|
|
25680
|
-
bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
|
|
25681
|
-
}
|
|
25682
|
-
return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
|
|
25683
|
-
getPureFunctionReturnValue(lView, bindingIndex);
|
|
25684
|
-
}
|
|
25685
|
-
|
|
25686
|
-
/**
|
|
25687
|
-
* Create a pipe.
|
|
25688
|
-
*
|
|
25689
|
-
* @param index Pipe index where the pipe will be stored.
|
|
25690
|
-
* @param pipeName The name of the pipe
|
|
25691
|
-
* @returns T the instance of the pipe.
|
|
25692
|
-
*
|
|
25693
|
-
* @codeGenApi
|
|
25694
|
-
*/
|
|
25695
|
-
function ɵɵpipe(index, pipeName) {
|
|
25696
|
-
const tView = getTView();
|
|
25697
|
-
let pipeDef;
|
|
25698
|
-
const adjustedIndex = index + HEADER_OFFSET;
|
|
25699
|
-
if (tView.firstCreatePass) {
|
|
25700
|
-
// The `getPipeDef` throws if a pipe with a given name is not found
|
|
25701
|
-
// (so we use non-null assertion below).
|
|
25702
|
-
pipeDef = getPipeDef(pipeName, tView.pipeRegistry);
|
|
25703
|
-
tView.data[adjustedIndex] = pipeDef;
|
|
25704
|
-
if (pipeDef.onDestroy) {
|
|
25705
|
-
(tView.destroyHooks ??= []).push(adjustedIndex, pipeDef.onDestroy);
|
|
25706
|
-
}
|
|
25707
|
-
}
|
|
25708
|
-
else {
|
|
25709
|
-
pipeDef = tView.data[adjustedIndex];
|
|
25710
|
-
}
|
|
25711
|
-
const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
|
|
25712
|
-
let previousInjectorProfilerContext;
|
|
25713
|
-
if (ngDevMode) {
|
|
25714
|
-
previousInjectorProfilerContext = setInjectorProfilerContext({
|
|
25715
|
-
injector: new NodeInjector(getCurrentTNode(), getLView()),
|
|
25716
|
-
token: pipeDef.type
|
|
25717
|
-
});
|
|
25718
|
-
}
|
|
25719
|
-
const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
|
|
25720
|
-
try {
|
|
25721
|
-
// DI for pipes is supposed to behave like directives when placed on a component
|
|
25722
|
-
// host node, which means that we have to disable access to `viewProviders`.
|
|
25723
|
-
const previousIncludeViewProviders = setIncludeViewProviders(false);
|
|
25724
|
-
const pipeInstance = pipeFactory();
|
|
25725
|
-
setIncludeViewProviders(previousIncludeViewProviders);
|
|
25726
|
-
store(tView, getLView(), adjustedIndex, pipeInstance);
|
|
25727
|
-
return pipeInstance;
|
|
25728
|
-
}
|
|
25729
|
-
finally {
|
|
25730
|
-
// we have to restore the injector implementation in finally, just in case the creation of the
|
|
25731
|
-
// pipe throws an error.
|
|
25732
|
-
setInjectImplementation(previousInjectImplementation);
|
|
25733
|
-
ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
|
|
25734
|
-
}
|
|
25735
|
-
}
|
|
25736
|
-
/**
|
|
25737
|
-
* Searches the pipe registry for a pipe with the given name. If one is found,
|
|
25738
|
-
* returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
|
|
25739
|
-
*
|
|
25740
|
-
* @param name Name of pipe to resolve
|
|
25741
|
-
* @param registry Full list of available pipes
|
|
25742
|
-
* @returns Matching PipeDef
|
|
25743
|
-
*/
|
|
25744
|
-
function getPipeDef(name, registry) {
|
|
25745
|
-
if (registry) {
|
|
25746
|
-
if (ngDevMode) {
|
|
25747
|
-
const pipes = registry.filter(pipe => pipe.name === name);
|
|
25748
|
-
// TODO: Throw an error in the next major
|
|
25749
|
-
if (pipes.length > 1) {
|
|
25750
|
-
console.warn(formatRuntimeError(313 /* RuntimeErrorCode.MULTIPLE_MATCHING_PIPES */, getMultipleMatchingPipesMessage(name)));
|
|
25751
|
-
}
|
|
25752
|
-
}
|
|
25753
|
-
for (let i = registry.length - 1; i >= 0; i--) {
|
|
25754
|
-
const pipeDef = registry[i];
|
|
25755
|
-
if (name === pipeDef.name) {
|
|
25756
|
-
return pipeDef;
|
|
25757
|
-
}
|
|
25758
|
-
}
|
|
25759
|
-
}
|
|
25760
|
-
if (ngDevMode) {
|
|
25761
|
-
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
|
|
25762
|
-
}
|
|
25763
|
-
}
|
|
25764
|
-
/**
|
|
25765
|
-
* Generates a helpful error message for the user when multiple pipes match the name.
|
|
25766
|
-
*
|
|
25767
|
-
* @param name Name of the pipe
|
|
25768
|
-
* @returns The error message
|
|
25769
|
-
*/
|
|
25770
|
-
function getMultipleMatchingPipesMessage(name) {
|
|
25771
|
-
const lView = getLView();
|
|
25772
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
25773
|
-
const context = declarationLView[CONTEXT];
|
|
25774
|
-
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
25775
|
-
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
25776
|
-
const verifyMessage = `check ${hostIsStandalone ? '\'@Component.imports\' of this component' :
|
|
25777
|
-
'the imports of this module'}`;
|
|
25778
|
-
const errorMessage = `Multiple pipes match the name \`${name}\`${componentInfoMessage}. ${verifyMessage}`;
|
|
25779
|
-
return errorMessage;
|
|
25780
|
-
}
|
|
25781
|
-
/**
|
|
25782
|
-
* Generates a helpful error message for the user when a pipe is not found.
|
|
25783
|
-
*
|
|
25784
|
-
* @param name Name of the missing pipe
|
|
25785
|
-
* @returns The error message
|
|
25786
|
-
*/
|
|
25787
|
-
function getPipeNotFoundErrorMessage(name) {
|
|
25788
|
-
const lView = getLView();
|
|
25789
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
25790
|
-
const context = declarationLView[CONTEXT];
|
|
25791
|
-
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
25792
|
-
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
25793
|
-
const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
25794
|
-
'declared or imported in this module'}`;
|
|
25795
|
-
const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
|
|
25796
|
-
return errorMessage;
|
|
25797
|
-
}
|
|
25798
|
-
/**
|
|
25799
|
-
* Invokes a pipe with 1 arguments.
|
|
25800
|
-
*
|
|
25801
|
-
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
25802
|
-
* the pipe only when an input to the pipe changes.
|
|
25803
|
-
*
|
|
25804
|
-
* @param index Pipe index where the pipe was stored on creation.
|
|
25805
|
-
* @param slotOffset the offset in the reserved slot space
|
|
25806
|
-
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
25807
|
-
*
|
|
25808
|
-
* @codeGenApi
|
|
25809
|
-
*/
|
|
25810
|
-
function ɵɵpipeBind1(index, slotOffset, v1) {
|
|
25811
|
-
const adjustedIndex = index + HEADER_OFFSET;
|
|
25812
|
-
const lView = getLView();
|
|
25813
|
-
const pipeInstance = load(lView, adjustedIndex);
|
|
25814
|
-
return isPure(lView, adjustedIndex) ?
|
|
25815
|
-
pureFunction1Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) :
|
|
25816
|
-
pipeInstance.transform(v1);
|
|
25817
|
-
}
|
|
25818
|
-
/**
|
|
25819
|
-
* Invokes a pipe with 2 arguments.
|
|
25820
|
-
*
|
|
25821
|
-
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
25822
|
-
* the pipe only when an input to the pipe changes.
|
|
25823
|
-
*
|
|
25824
|
-
* @param index Pipe index where the pipe was stored on creation.
|
|
25825
|
-
* @param slotOffset the offset in the reserved slot space
|
|
25826
|
-
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
25827
|
-
* @param v2 2nd argument to {@link PipeTransform#transform}.
|
|
25828
|
-
*
|
|
25829
|
-
* @codeGenApi
|
|
25830
|
-
*/
|
|
25831
|
-
function ɵɵpipeBind2(index, slotOffset, v1, v2) {
|
|
25832
|
-
const adjustedIndex = index + HEADER_OFFSET;
|
|
25833
|
-
const lView = getLView();
|
|
25834
|
-
const pipeInstance = load(lView, adjustedIndex);
|
|
25835
|
-
return isPure(lView, adjustedIndex) ?
|
|
25836
|
-
pureFunction2Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
|
|
25837
|
-
pipeInstance.transform(v1, v2);
|
|
25838
|
-
}
|
|
25839
|
-
/**
|
|
25840
|
-
* Invokes a pipe with 3 arguments.
|
|
25841
|
-
*
|
|
25842
|
-
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
25843
|
-
* the pipe only when an input to the pipe changes.
|
|
25844
|
-
*
|
|
25845
|
-
* @param index Pipe index where the pipe was stored on creation.
|
|
25846
|
-
* @param slotOffset the offset in the reserved slot space
|
|
25847
|
-
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
25848
|
-
* @param v2 2nd argument to {@link PipeTransform#transform}.
|
|
25849
|
-
* @param v3 4rd argument to {@link PipeTransform#transform}.
|
|
25850
|
-
*
|
|
25851
26125
|
* @codeGenApi
|
|
25852
26126
|
*/
|
|
25853
|
-
function ɵɵ
|
|
25854
|
-
|
|
25855
|
-
const lView = getLView();
|
|
25856
|
-
const pipeInstance = load(lView, adjustedIndex);
|
|
25857
|
-
return isPure(lView, adjustedIndex) ?
|
|
25858
|
-
pureFunction3Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
|
|
25859
|
-
pipeInstance.transform(v1, v2, v3);
|
|
26127
|
+
function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
|
|
26128
|
+
return pureFunction4Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
|
|
25860
26129
|
}
|
|
25861
26130
|
/**
|
|
25862
|
-
*
|
|
25863
|
-
*
|
|
25864
|
-
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
25865
|
-
* the pipe only when an input to the pipe changes.
|
|
26131
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26132
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
25866
26133
|
*
|
|
25867
|
-
* @param
|
|
25868
|
-
* @param
|
|
25869
|
-
* @param
|
|
25870
|
-
* @param
|
|
25871
|
-
* @param
|
|
25872
|
-
* @param
|
|
26134
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26135
|
+
* @param pureFn
|
|
26136
|
+
* @param exp1
|
|
26137
|
+
* @param exp2
|
|
26138
|
+
* @param exp3
|
|
26139
|
+
* @param exp4
|
|
26140
|
+
* @param exp5
|
|
26141
|
+
* @param thisArg Optional calling context of pureFn
|
|
26142
|
+
* @returns Updated or cached value
|
|
25873
26143
|
*
|
|
25874
26144
|
* @codeGenApi
|
|
25875
26145
|
*/
|
|
25876
|
-
function ɵɵ
|
|
25877
|
-
const
|
|
26146
|
+
function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
|
|
26147
|
+
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25878
26148
|
const lView = getLView();
|
|
25879
|
-
const
|
|
25880
|
-
return
|
|
25881
|
-
|
|
26149
|
+
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
26150
|
+
return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
|
|
26151
|
+
updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
|
|
26152
|
+
pureFn(exp1, exp2, exp3, exp4, exp5)) :
|
|
26153
|
+
getBinding(lView, bindingIndex + 5);
|
|
25882
26154
|
}
|
|
25883
26155
|
/**
|
|
25884
|
-
*
|
|
25885
|
-
*
|
|
25886
|
-
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
25887
|
-
* the pipe only when an input to the pipe changes.
|
|
26156
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26157
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
25888
26158
|
*
|
|
25889
|
-
* @param
|
|
25890
|
-
* @param
|
|
25891
|
-
* @param
|
|
26159
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26160
|
+
* @param pureFn
|
|
26161
|
+
* @param exp1
|
|
26162
|
+
* @param exp2
|
|
26163
|
+
* @param exp3
|
|
26164
|
+
* @param exp4
|
|
26165
|
+
* @param exp5
|
|
26166
|
+
* @param exp6
|
|
26167
|
+
* @param thisArg Optional calling context of pureFn
|
|
26168
|
+
* @returns Updated or cached value
|
|
25892
26169
|
*
|
|
25893
26170
|
* @codeGenApi
|
|
25894
26171
|
*/
|
|
25895
|
-
function
|
|
25896
|
-
const
|
|
26172
|
+
function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
|
|
26173
|
+
const bindingIndex = getBindingRoot() + slotOffset;
|
|
25897
26174
|
const lView = getLView();
|
|
25898
|
-
const
|
|
25899
|
-
return
|
|
25900
|
-
|
|
25901
|
-
|
|
25902
|
-
|
|
25903
|
-
function isPure(lView, index) {
|
|
25904
|
-
return lView[TVIEW].data[index].pure;
|
|
25905
|
-
}
|
|
25906
|
-
|
|
25907
|
-
function symbolIterator() {
|
|
25908
|
-
// @ts-expect-error accessing a private member
|
|
25909
|
-
return this._results[Symbol.iterator]();
|
|
26175
|
+
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
26176
|
+
return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
|
|
26177
|
+
updateBinding(lView, bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
|
|
26178
|
+
pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
|
|
26179
|
+
getBinding(lView, bindingIndex + 6);
|
|
25910
26180
|
}
|
|
25911
26181
|
/**
|
|
25912
|
-
*
|
|
25913
|
-
*
|
|
25914
|
-
*
|
|
25915
|
-
* The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
|
|
25916
|
-
* provide.
|
|
25917
|
-
*
|
|
25918
|
-
* Implements an iterable interface, therefore it can be used in both ES6
|
|
25919
|
-
* javascript `for (var i of items)` loops as well as in Angular templates with
|
|
25920
|
-
* `*ngFor="let i of myList"`.
|
|
25921
|
-
*
|
|
25922
|
-
* Changes can be observed by subscribing to the changes `Observable`.
|
|
25923
|
-
*
|
|
25924
|
-
* NOTE: In the future this class will implement an `Observable` interface.
|
|
26182
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26183
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
25925
26184
|
*
|
|
25926
|
-
* @
|
|
25927
|
-
*
|
|
25928
|
-
*
|
|
25929
|
-
* @
|
|
25930
|
-
*
|
|
25931
|
-
*
|
|
25932
|
-
*
|
|
25933
|
-
*
|
|
26185
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26186
|
+
* @param pureFn
|
|
26187
|
+
* @param exp1
|
|
26188
|
+
* @param exp2
|
|
26189
|
+
* @param exp3
|
|
26190
|
+
* @param exp4
|
|
26191
|
+
* @param exp5
|
|
26192
|
+
* @param exp6
|
|
26193
|
+
* @param exp7
|
|
26194
|
+
* @param thisArg Optional calling context of pureFn
|
|
26195
|
+
* @returns Updated or cached value
|
|
25934
26196
|
*
|
|
25935
|
-
* @
|
|
26197
|
+
* @codeGenApi
|
|
25936
26198
|
*/
|
|
25937
|
-
|
|
25938
|
-
|
|
25939
|
-
|
|
25940
|
-
|
|
25941
|
-
|
|
25942
|
-
|
|
25943
|
-
|
|
25944
|
-
|
|
25945
|
-
|
|
25946
|
-
|
|
25947
|
-
|
|
25948
|
-
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
|
|
25952
|
-
|
|
25953
|
-
|
|
25954
|
-
|
|
25955
|
-
|
|
25956
|
-
|
|
25957
|
-
|
|
25958
|
-
|
|
25959
|
-
|
|
25960
|
-
|
|
25961
|
-
|
|
25962
|
-
|
|
25963
|
-
|
|
25964
|
-
|
|
25965
|
-
|
|
25966
|
-
|
|
25967
|
-
|
|
25968
|
-
|
|
25969
|
-
|
|
25970
|
-
|
|
25971
|
-
|
|
25972
|
-
|
|
25973
|
-
/**
|
|
25974
|
-
* See
|
|
25975
|
-
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
|
|
25976
|
-
*/
|
|
25977
|
-
map(fn) {
|
|
25978
|
-
return this._results.map(fn);
|
|
25979
|
-
}
|
|
25980
|
-
filter(fn) {
|
|
25981
|
-
return this._results.filter(fn);
|
|
25982
|
-
}
|
|
25983
|
-
/**
|
|
25984
|
-
* See
|
|
25985
|
-
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
|
|
25986
|
-
*/
|
|
25987
|
-
find(fn) {
|
|
25988
|
-
return this._results.find(fn);
|
|
25989
|
-
}
|
|
25990
|
-
/**
|
|
25991
|
-
* See
|
|
25992
|
-
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
|
|
25993
|
-
*/
|
|
25994
|
-
reduce(fn, init) {
|
|
25995
|
-
return this._results.reduce(fn, init);
|
|
25996
|
-
}
|
|
25997
|
-
/**
|
|
25998
|
-
* See
|
|
25999
|
-
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
|
|
26000
|
-
*/
|
|
26001
|
-
forEach(fn) {
|
|
26002
|
-
this._results.forEach(fn);
|
|
26003
|
-
}
|
|
26004
|
-
/**
|
|
26005
|
-
* See
|
|
26006
|
-
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
|
|
26007
|
-
*/
|
|
26008
|
-
some(fn) {
|
|
26009
|
-
return this._results.some(fn);
|
|
26010
|
-
}
|
|
26011
|
-
/**
|
|
26012
|
-
* Returns a copy of the internal results list as an Array.
|
|
26013
|
-
*/
|
|
26014
|
-
toArray() {
|
|
26015
|
-
return this._results.slice();
|
|
26016
|
-
}
|
|
26017
|
-
toString() {
|
|
26018
|
-
return this._results.toString();
|
|
26019
|
-
}
|
|
26020
|
-
/**
|
|
26021
|
-
* Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
|
|
26022
|
-
* on change detection, it will not notify of changes to the queries, unless a new change
|
|
26023
|
-
* occurs.
|
|
26024
|
-
*
|
|
26025
|
-
* @param resultsTree The query results to store
|
|
26026
|
-
* @param identityAccessor Optional function for extracting stable object identity from a value
|
|
26027
|
-
* in the array. This function is executed for each element of the query result list while
|
|
26028
|
-
* comparing current query list with the new one (provided as a first argument of the `reset`
|
|
26029
|
-
* function) to detect if the lists are different. If the function is not provided, elements
|
|
26030
|
-
* are compared as is (without any pre-processing).
|
|
26031
|
-
*/
|
|
26032
|
-
reset(resultsTree, identityAccessor) {
|
|
26033
|
-
// Cast to `QueryListInternal` so that we can mutate fields which are readonly for the usage of
|
|
26034
|
-
// QueryList (but not for QueryList itself.)
|
|
26035
|
-
const self = this;
|
|
26036
|
-
self.dirty = false;
|
|
26037
|
-
const newResultFlat = flatten(resultsTree);
|
|
26038
|
-
if (this._changesDetected = !arrayEquals(self._results, newResultFlat, identityAccessor)) {
|
|
26039
|
-
self._results = newResultFlat;
|
|
26040
|
-
self.length = newResultFlat.length;
|
|
26041
|
-
self.last = newResultFlat[this.length - 1];
|
|
26042
|
-
self.first = newResultFlat[0];
|
|
26043
|
-
}
|
|
26044
|
-
}
|
|
26045
|
-
/**
|
|
26046
|
-
* Triggers a change event by emitting on the `changes` {@link EventEmitter}.
|
|
26047
|
-
*/
|
|
26048
|
-
notifyOnChanges() {
|
|
26049
|
-
if (this._changes && (this._changesDetected || !this._emitDistinctChangesOnly))
|
|
26050
|
-
this._changes.emit(this);
|
|
26051
|
-
}
|
|
26052
|
-
/** internal */
|
|
26053
|
-
setDirty() {
|
|
26054
|
-
this.dirty = true;
|
|
26055
|
-
}
|
|
26056
|
-
/** internal */
|
|
26057
|
-
destroy() {
|
|
26058
|
-
this.changes.complete();
|
|
26059
|
-
this.changes.unsubscribe();
|
|
26060
|
-
}
|
|
26199
|
+
function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
|
|
26200
|
+
const bindingIndex = getBindingRoot() + slotOffset;
|
|
26201
|
+
const lView = getLView();
|
|
26202
|
+
let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
26203
|
+
return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
|
|
26204
|
+
updateBinding(lView, bindingIndex + 7, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
|
|
26205
|
+
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
|
|
26206
|
+
getBinding(lView, bindingIndex + 7);
|
|
26207
|
+
}
|
|
26208
|
+
/**
|
|
26209
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26210
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26211
|
+
*
|
|
26212
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26213
|
+
* @param pureFn
|
|
26214
|
+
* @param exp1
|
|
26215
|
+
* @param exp2
|
|
26216
|
+
* @param exp3
|
|
26217
|
+
* @param exp4
|
|
26218
|
+
* @param exp5
|
|
26219
|
+
* @param exp6
|
|
26220
|
+
* @param exp7
|
|
26221
|
+
* @param exp8
|
|
26222
|
+
* @param thisArg Optional calling context of pureFn
|
|
26223
|
+
* @returns Updated or cached value
|
|
26224
|
+
*
|
|
26225
|
+
* @codeGenApi
|
|
26226
|
+
*/
|
|
26227
|
+
function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
|
|
26228
|
+
const bindingIndex = getBindingRoot() + slotOffset;
|
|
26229
|
+
const lView = getLView();
|
|
26230
|
+
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
|
26231
|
+
return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
|
|
26232
|
+
updateBinding(lView, bindingIndex + 8, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
|
|
26233
|
+
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
|
|
26234
|
+
getBinding(lView, bindingIndex + 8);
|
|
26061
26235
|
}
|
|
26062
|
-
|
|
26063
26236
|
/**
|
|
26064
|
-
*
|
|
26065
|
-
* To instantiate embedded views based on a template, use the `ViewContainerRef`
|
|
26066
|
-
* method `createEmbeddedView()`.
|
|
26237
|
+
* pureFunction instruction that can support any number of bindings.
|
|
26067
26238
|
*
|
|
26068
|
-
*
|
|
26069
|
-
*
|
|
26070
|
-
* is injected into the constructor of the directive,
|
|
26071
|
-
* using the `TemplateRef` token.
|
|
26239
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26240
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26072
26241
|
*
|
|
26073
|
-
*
|
|
26074
|
-
*
|
|
26242
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26243
|
+
* @param pureFn A pure function that takes binding values and builds an object or array
|
|
26244
|
+
* containing those values.
|
|
26245
|
+
* @param exps An array of binding values
|
|
26246
|
+
* @param thisArg Optional calling context of pureFn
|
|
26247
|
+
* @returns Updated or cached value
|
|
26075
26248
|
*
|
|
26076
|
-
* @
|
|
26077
|
-
|
|
26249
|
+
* @codeGenApi
|
|
26250
|
+
*/
|
|
26251
|
+
function ɵɵpureFunctionV(slotOffset, pureFn, exps, thisArg) {
|
|
26252
|
+
return pureFunctionVInternal(getLView(), getBindingRoot(), slotOffset, pureFn, exps, thisArg);
|
|
26253
|
+
}
|
|
26254
|
+
/**
|
|
26255
|
+
* Results of a pure function invocation are stored in LView in a dedicated slot that is initialized
|
|
26256
|
+
* to NO_CHANGE. In rare situations a pure pipe might throw an exception on the very first
|
|
26257
|
+
* invocation and not produce any valid results. In this case LView would keep holding the NO_CHANGE
|
|
26258
|
+
* value. The NO_CHANGE is not something that we can use in expressions / bindings thus we convert
|
|
26259
|
+
* it to `undefined`.
|
|
26260
|
+
*/
|
|
26261
|
+
function getPureFunctionReturnValue(lView, returnValueIndex) {
|
|
26262
|
+
ngDevMode && assertIndexInRange(lView, returnValueIndex);
|
|
26263
|
+
const lastReturnValue = lView[returnValueIndex];
|
|
26264
|
+
return lastReturnValue === NO_CHANGE ? undefined : lastReturnValue;
|
|
26265
|
+
}
|
|
26266
|
+
/**
|
|
26267
|
+
* If the value of the provided exp has changed, calls the pure function to return
|
|
26268
|
+
* an updated value. Or if the value has not changed, returns cached value.
|
|
26078
26269
|
*
|
|
26079
|
-
* @
|
|
26270
|
+
* @param lView LView in which the function is being executed.
|
|
26271
|
+
* @param bindingRoot Binding root index.
|
|
26272
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26273
|
+
* @param pureFn Function that returns an updated value
|
|
26274
|
+
* @param exp Updated expression value
|
|
26275
|
+
* @param thisArg Optional calling context of pureFn
|
|
26276
|
+
* @returns Updated or cached value
|
|
26080
26277
|
*/
|
|
26081
|
-
|
|
26082
|
-
|
|
26083
|
-
|
|
26084
|
-
|
|
26085
|
-
|
|
26086
|
-
static { this.__NG_ELEMENT_ID__ = injectTemplateRef; }
|
|
26278
|
+
function pureFunction1Internal(lView, bindingRoot, slotOffset, pureFn, exp, thisArg) {
|
|
26279
|
+
const bindingIndex = bindingRoot + slotOffset;
|
|
26280
|
+
return bindingUpdated(lView, bindingIndex, exp) ?
|
|
26281
|
+
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
|
|
26282
|
+
getPureFunctionReturnValue(lView, bindingIndex + 1);
|
|
26087
26283
|
}
|
|
26088
|
-
const ViewEngineTemplateRef = TemplateRef;
|
|
26089
|
-
// TODO(alxhub): combine interface and implementation. Currently this is challenging since something
|
|
26090
|
-
// in g3 depends on them being separate.
|
|
26091
|
-
const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
|
|
26092
|
-
constructor(_declarationLView, _declarationTContainer, elementRef) {
|
|
26093
|
-
super();
|
|
26094
|
-
this._declarationLView = _declarationLView;
|
|
26095
|
-
this._declarationTContainer = _declarationTContainer;
|
|
26096
|
-
this.elementRef = elementRef;
|
|
26097
|
-
}
|
|
26098
|
-
/**
|
|
26099
|
-
* Returns an `ssrId` associated with a TView, which was used to
|
|
26100
|
-
* create this instance of the `TemplateRef`.
|
|
26101
|
-
*
|
|
26102
|
-
* @internal
|
|
26103
|
-
*/
|
|
26104
|
-
get ssrId() {
|
|
26105
|
-
return this._declarationTContainer.tView?.ssrId || null;
|
|
26106
|
-
}
|
|
26107
|
-
createEmbeddedView(context, injector) {
|
|
26108
|
-
return this.createEmbeddedViewImpl(context, injector);
|
|
26109
|
-
}
|
|
26110
|
-
/**
|
|
26111
|
-
* @internal
|
|
26112
|
-
*/
|
|
26113
|
-
createEmbeddedViewImpl(context, injector, hydrationInfo) {
|
|
26114
|
-
const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { injector, hydrationInfo });
|
|
26115
|
-
return new ViewRef$1(embeddedLView);
|
|
26116
|
-
}
|
|
26117
|
-
};
|
|
26118
26284
|
/**
|
|
26119
|
-
*
|
|
26285
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26286
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26120
26287
|
*
|
|
26121
|
-
* @
|
|
26288
|
+
* @param lView LView in which the function is being executed.
|
|
26289
|
+
* @param bindingRoot Binding root index.
|
|
26290
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26291
|
+
* @param pureFn
|
|
26292
|
+
* @param exp1
|
|
26293
|
+
* @param exp2
|
|
26294
|
+
* @param thisArg Optional calling context of pureFn
|
|
26295
|
+
* @returns Updated or cached value
|
|
26122
26296
|
*/
|
|
26123
|
-
function
|
|
26124
|
-
|
|
26297
|
+
function pureFunction2Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, thisArg) {
|
|
26298
|
+
const bindingIndex = bindingRoot + slotOffset;
|
|
26299
|
+
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
|
|
26300
|
+
updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
|
|
26301
|
+
getPureFunctionReturnValue(lView, bindingIndex + 2);
|
|
26125
26302
|
}
|
|
26126
26303
|
/**
|
|
26127
|
-
*
|
|
26304
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26305
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26128
26306
|
*
|
|
26129
|
-
* @param
|
|
26130
|
-
* @param
|
|
26131
|
-
* @
|
|
26307
|
+
* @param lView LView in which the function is being executed.
|
|
26308
|
+
* @param bindingRoot Binding root index.
|
|
26309
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26310
|
+
* @param pureFn
|
|
26311
|
+
* @param exp1
|
|
26312
|
+
* @param exp2
|
|
26313
|
+
* @param exp3
|
|
26314
|
+
* @param thisArg Optional calling context of pureFn
|
|
26315
|
+
* @returns Updated or cached value
|
|
26132
26316
|
*/
|
|
26133
|
-
function
|
|
26134
|
-
|
|
26135
|
-
|
|
26136
|
-
|
|
26317
|
+
function pureFunction3Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
|
|
26318
|
+
const bindingIndex = bindingRoot + slotOffset;
|
|
26319
|
+
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
|
|
26320
|
+
updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
|
|
26321
|
+
getPureFunctionReturnValue(lView, bindingIndex + 3);
|
|
26322
|
+
}
|
|
26323
|
+
/**
|
|
26324
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26325
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26326
|
+
*
|
|
26327
|
+
* @param lView LView in which the function is being executed.
|
|
26328
|
+
* @param bindingRoot Binding root index.
|
|
26329
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26330
|
+
* @param pureFn
|
|
26331
|
+
* @param exp1
|
|
26332
|
+
* @param exp2
|
|
26333
|
+
* @param exp3
|
|
26334
|
+
* @param exp4
|
|
26335
|
+
* @param thisArg Optional calling context of pureFn
|
|
26336
|
+
* @returns Updated or cached value
|
|
26337
|
+
*
|
|
26338
|
+
*/
|
|
26339
|
+
function pureFunction4Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
|
|
26340
|
+
const bindingIndex = bindingRoot + slotOffset;
|
|
26341
|
+
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
|
|
26342
|
+
updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
|
|
26343
|
+
getPureFunctionReturnValue(lView, bindingIndex + 4);
|
|
26344
|
+
}
|
|
26345
|
+
/**
|
|
26346
|
+
* pureFunction instruction that can support any number of bindings.
|
|
26347
|
+
*
|
|
26348
|
+
* If the value of any provided exp has changed, calls the pure function to return
|
|
26349
|
+
* an updated value. Or if no values have changed, returns cached value.
|
|
26350
|
+
*
|
|
26351
|
+
* @param lView LView in which the function is being executed.
|
|
26352
|
+
* @param bindingRoot Binding root index.
|
|
26353
|
+
* @param slotOffset the offset from binding root to the reserved slot
|
|
26354
|
+
* @param pureFn A pure function that takes binding values and builds an object or array
|
|
26355
|
+
* containing those values.
|
|
26356
|
+
* @param exps An array of binding values
|
|
26357
|
+
* @param thisArg Optional calling context of pureFn
|
|
26358
|
+
* @returns Updated or cached value
|
|
26359
|
+
*/
|
|
26360
|
+
function pureFunctionVInternal(lView, bindingRoot, slotOffset, pureFn, exps, thisArg) {
|
|
26361
|
+
let bindingIndex = bindingRoot + slotOffset;
|
|
26362
|
+
let different = false;
|
|
26363
|
+
for (let i = 0; i < exps.length; i++) {
|
|
26364
|
+
bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
|
|
26137
26365
|
}
|
|
26138
|
-
return
|
|
26366
|
+
return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
|
|
26367
|
+
getPureFunctionReturnValue(lView, bindingIndex);
|
|
26139
26368
|
}
|
|
26140
26369
|
|
|
26141
26370
|
/**
|
|
26142
|
-
*
|
|
26143
|
-
*
|
|
26144
|
-
*
|
|
26371
|
+
* Create a pipe.
|
|
26372
|
+
*
|
|
26373
|
+
* @param index Pipe index where the pipe will be stored.
|
|
26374
|
+
* @param pipeName The name of the pipe
|
|
26375
|
+
* @returns T the instance of the pipe.
|
|
26376
|
+
*
|
|
26377
|
+
* @codeGenApi
|
|
26145
26378
|
*/
|
|
26146
|
-
function
|
|
26147
|
-
const
|
|
26148
|
-
|
|
26149
|
-
const
|
|
26150
|
-
|
|
26151
|
-
|
|
26152
|
-
|
|
26379
|
+
function ɵɵpipe(index, pipeName) {
|
|
26380
|
+
const tView = getTView();
|
|
26381
|
+
let pipeDef;
|
|
26382
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26383
|
+
if (tView.firstCreatePass) {
|
|
26384
|
+
// The `getPipeDef` throws if a pipe with a given name is not found
|
|
26385
|
+
// (so we use non-null assertion below).
|
|
26386
|
+
pipeDef = getPipeDef(pipeName, tView.pipeRegistry);
|
|
26387
|
+
tView.data[adjustedIndex] = pipeDef;
|
|
26388
|
+
if (pipeDef.onDestroy) {
|
|
26389
|
+
(tView.destroyHooks ??= []).push(adjustedIndex, pipeDef.onDestroy);
|
|
26390
|
+
}
|
|
26391
|
+
}
|
|
26392
|
+
else {
|
|
26393
|
+
pipeDef = tView.data[adjustedIndex];
|
|
26394
|
+
}
|
|
26395
|
+
const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
|
|
26396
|
+
let previousInjectorProfilerContext;
|
|
26397
|
+
if (ngDevMode) {
|
|
26398
|
+
previousInjectorProfilerContext = setInjectorProfilerContext({
|
|
26399
|
+
injector: new NodeInjector(getCurrentTNode(), getLView()),
|
|
26400
|
+
token: pipeDef.type
|
|
26401
|
+
});
|
|
26402
|
+
}
|
|
26403
|
+
const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
|
|
26404
|
+
try {
|
|
26405
|
+
// DI for pipes is supposed to behave like directives when placed on a component
|
|
26406
|
+
// host node, which means that we have to disable access to `viewProviders`.
|
|
26407
|
+
const previousIncludeViewProviders = setIncludeViewProviders(false);
|
|
26408
|
+
const pipeInstance = pipeFactory();
|
|
26409
|
+
setIncludeViewProviders(previousIncludeViewProviders);
|
|
26410
|
+
store(tView, getLView(), adjustedIndex, pipeInstance);
|
|
26411
|
+
return pipeInstance;
|
|
26412
|
+
}
|
|
26413
|
+
finally {
|
|
26414
|
+
// we have to restore the injector implementation in finally, just in case the creation of the
|
|
26415
|
+
// pipe throws an error.
|
|
26416
|
+
setInjectImplementation(previousInjectImplementation);
|
|
26417
|
+
ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
|
|
26153
26418
|
}
|
|
26154
|
-
// Reset the value to an empty array to indicate that no
|
|
26155
|
-
// further processing of dehydrated views is needed for
|
|
26156
|
-
// this view container (i.e. do not trigger the lookup process
|
|
26157
|
-
// once again in case a `ViewContainerRef` is created later).
|
|
26158
|
-
lContainer[DEHYDRATED_VIEWS] = EMPTY_ARRAY;
|
|
26159
26419
|
}
|
|
26160
26420
|
/**
|
|
26161
|
-
*
|
|
26421
|
+
* Searches the pipe registry for a pipe with the given name. If one is found,
|
|
26422
|
+
* returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
|
|
26423
|
+
*
|
|
26424
|
+
* @param name Name of pipe to resolve
|
|
26425
|
+
* @param registry Full list of available pipes
|
|
26426
|
+
* @returns Matching PipeDef
|
|
26162
26427
|
*/
|
|
26163
|
-
function
|
|
26164
|
-
|
|
26165
|
-
|
|
26166
|
-
|
|
26167
|
-
|
|
26168
|
-
|
|
26169
|
-
|
|
26170
|
-
|
|
26171
|
-
|
|
26172
|
-
|
|
26173
|
-
|
|
26428
|
+
function getPipeDef(name, registry) {
|
|
26429
|
+
if (registry) {
|
|
26430
|
+
if (ngDevMode) {
|
|
26431
|
+
const pipes = registry.filter(pipe => pipe.name === name);
|
|
26432
|
+
// TODO: Throw an error in the next major
|
|
26433
|
+
if (pipes.length > 1) {
|
|
26434
|
+
console.warn(formatRuntimeError(313 /* RuntimeErrorCode.MULTIPLE_MATCHING_PIPES */, getMultipleMatchingPipesMessage(name)));
|
|
26435
|
+
}
|
|
26436
|
+
}
|
|
26437
|
+
for (let i = registry.length - 1; i >= 0; i--) {
|
|
26438
|
+
const pipeDef = registry[i];
|
|
26439
|
+
if (name === pipeDef.name) {
|
|
26440
|
+
return pipeDef;
|
|
26441
|
+
}
|
|
26174
26442
|
}
|
|
26175
26443
|
}
|
|
26444
|
+
if (ngDevMode) {
|
|
26445
|
+
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
|
|
26446
|
+
}
|
|
26176
26447
|
}
|
|
26177
26448
|
/**
|
|
26178
|
-
*
|
|
26179
|
-
*
|
|
26449
|
+
* Generates a helpful error message for the user when multiple pipes match the name.
|
|
26450
|
+
*
|
|
26451
|
+
* @param name Name of the pipe
|
|
26452
|
+
* @returns The error message
|
|
26180
26453
|
*/
|
|
26181
|
-
function
|
|
26182
|
-
|
|
26183
|
-
|
|
26184
|
-
|
|
26185
|
-
|
|
26454
|
+
function getMultipleMatchingPipesMessage(name) {
|
|
26455
|
+
const lView = getLView();
|
|
26456
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
26457
|
+
const context = declarationLView[CONTEXT];
|
|
26458
|
+
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
26459
|
+
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
26460
|
+
const verifyMessage = `check ${hostIsStandalone ? '\'@Component.imports\' of this component' :
|
|
26461
|
+
'the imports of this module'}`;
|
|
26462
|
+
const errorMessage = `Multiple pipes match the name \`${name}\`${componentInfoMessage}. ${verifyMessage}`;
|
|
26463
|
+
return errorMessage;
|
|
26186
26464
|
}
|
|
26187
26465
|
/**
|
|
26188
|
-
*
|
|
26189
|
-
*
|
|
26466
|
+
* Generates a helpful error message for the user when a pipe is not found.
|
|
26467
|
+
*
|
|
26468
|
+
* @param name Name of the missing pipe
|
|
26469
|
+
* @returns The error message
|
|
26190
26470
|
*/
|
|
26191
|
-
function
|
|
26192
|
-
const
|
|
26193
|
-
|
|
26194
|
-
|
|
26195
|
-
|
|
26196
|
-
|
|
26197
|
-
|
|
26198
|
-
|
|
26199
|
-
|
|
26200
|
-
|
|
26201
|
-
}
|
|
26202
|
-
}
|
|
26471
|
+
function getPipeNotFoundErrorMessage(name) {
|
|
26472
|
+
const lView = getLView();
|
|
26473
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
26474
|
+
const context = declarationLView[CONTEXT];
|
|
26475
|
+
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
26476
|
+
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
26477
|
+
const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
26478
|
+
'declared or imported in this module'}`;
|
|
26479
|
+
const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
|
|
26480
|
+
return errorMessage;
|
|
26203
26481
|
}
|
|
26204
26482
|
/**
|
|
26205
|
-
*
|
|
26206
|
-
*
|
|
26483
|
+
* Invokes a pipe with 1 arguments.
|
|
26484
|
+
*
|
|
26485
|
+
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
26486
|
+
* the pipe only when an input to the pipe changes.
|
|
26487
|
+
*
|
|
26488
|
+
* @param index Pipe index where the pipe was stored on creation.
|
|
26489
|
+
* @param slotOffset the offset in the reserved slot space
|
|
26490
|
+
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
26491
|
+
*
|
|
26492
|
+
* @codeGenApi
|
|
26207
26493
|
*/
|
|
26208
|
-
function
|
|
26209
|
-
const
|
|
26210
|
-
|
|
26211
|
-
|
|
26212
|
-
|
|
26213
|
-
|
|
26214
|
-
|
|
26215
|
-
if (isLView(lNode)) {
|
|
26216
|
-
cleanupLView(lNode);
|
|
26217
|
-
}
|
|
26218
|
-
else {
|
|
26219
|
-
// Cleanup in the root component view
|
|
26220
|
-
const componentLView = lNode[HOST];
|
|
26221
|
-
cleanupLView(componentLView);
|
|
26222
|
-
// Cleanup in all views within this view container
|
|
26223
|
-
cleanupLContainer(lNode);
|
|
26224
|
-
}
|
|
26225
|
-
ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
|
|
26226
|
-
}
|
|
26227
|
-
}
|
|
26494
|
+
function ɵɵpipeBind1(index, slotOffset, v1) {
|
|
26495
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26496
|
+
const lView = getLView();
|
|
26497
|
+
const pipeInstance = load(lView, adjustedIndex);
|
|
26498
|
+
return isPure(lView, adjustedIndex) ?
|
|
26499
|
+
pureFunction1Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) :
|
|
26500
|
+
pipeInstance.transform(v1);
|
|
26228
26501
|
}
|
|
26229
|
-
|
|
26230
26502
|
/**
|
|
26231
|
-
*
|
|
26232
|
-
*
|
|
26233
|
-
*
|
|
26503
|
+
* Invokes a pipe with 2 arguments.
|
|
26504
|
+
*
|
|
26505
|
+
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
26506
|
+
* the pipe only when an input to the pipe changes.
|
|
26507
|
+
*
|
|
26508
|
+
* @param index Pipe index where the pipe was stored on creation.
|
|
26509
|
+
* @param slotOffset the offset in the reserved slot space
|
|
26510
|
+
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
26511
|
+
* @param v2 2nd argument to {@link PipeTransform#transform}.
|
|
26512
|
+
*
|
|
26513
|
+
* @codeGenApi
|
|
26234
26514
|
*/
|
|
26235
|
-
function
|
|
26236
|
-
const
|
|
26237
|
-
|
|
26238
|
-
|
|
26239
|
-
|
|
26240
|
-
|
|
26241
|
-
|
|
26242
|
-
data: serializedView,
|
|
26243
|
-
firstChild: null,
|
|
26244
|
-
};
|
|
26245
|
-
if (serializedView[NUM_ROOT_NODES] > 0) {
|
|
26246
|
-
// Keep reference to the first node in this view,
|
|
26247
|
-
// so it can be accessed while invoking template instructions.
|
|
26248
|
-
view.firstChild = currentRNode;
|
|
26249
|
-
// Move over to the next node after this view, which can
|
|
26250
|
-
// either be a first node of the next view or an anchor comment
|
|
26251
|
-
// node after the last view in a container.
|
|
26252
|
-
currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
|
|
26253
|
-
}
|
|
26254
|
-
dehydratedViews.push(view);
|
|
26255
|
-
}
|
|
26256
|
-
}
|
|
26257
|
-
return [currentRNode, dehydratedViews];
|
|
26515
|
+
function ɵɵpipeBind2(index, slotOffset, v1, v2) {
|
|
26516
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26517
|
+
const lView = getLView();
|
|
26518
|
+
const pipeInstance = load(lView, adjustedIndex);
|
|
26519
|
+
return isPure(lView, adjustedIndex) ?
|
|
26520
|
+
pureFunction2Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
|
|
26521
|
+
pipeInstance.transform(v1, v2);
|
|
26258
26522
|
}
|
|
26259
26523
|
/**
|
|
26260
|
-
*
|
|
26261
|
-
*
|
|
26262
|
-
*
|
|
26524
|
+
* Invokes a pipe with 3 arguments.
|
|
26525
|
+
*
|
|
26526
|
+
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
26527
|
+
* the pipe only when an input to the pipe changes.
|
|
26528
|
+
*
|
|
26529
|
+
* @param index Pipe index where the pipe was stored on creation.
|
|
26530
|
+
* @param slotOffset the offset in the reserved slot space
|
|
26531
|
+
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
26532
|
+
* @param v2 2nd argument to {@link PipeTransform#transform}.
|
|
26533
|
+
* @param v3 4rd argument to {@link PipeTransform#transform}.
|
|
26534
|
+
*
|
|
26535
|
+
* @codeGenApi
|
|
26263
26536
|
*/
|
|
26264
|
-
|
|
26537
|
+
function ɵɵpipeBind3(index, slotOffset, v1, v2, v3) {
|
|
26538
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26539
|
+
const lView = getLView();
|
|
26540
|
+
const pipeInstance = load(lView, adjustedIndex);
|
|
26541
|
+
return isPure(lView, adjustedIndex) ?
|
|
26542
|
+
pureFunction3Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
|
|
26543
|
+
pipeInstance.transform(v1, v2, v3);
|
|
26544
|
+
}
|
|
26265
26545
|
/**
|
|
26266
|
-
*
|
|
26267
|
-
*
|
|
26268
|
-
*
|
|
26269
|
-
*
|
|
26270
|
-
*
|
|
26271
|
-
*
|
|
26272
|
-
* in
|
|
26546
|
+
* Invokes a pipe with 4 arguments.
|
|
26547
|
+
*
|
|
26548
|
+
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
26549
|
+
* the pipe only when an input to the pipe changes.
|
|
26550
|
+
*
|
|
26551
|
+
* @param index Pipe index where the pipe was stored on creation.
|
|
26552
|
+
* @param slotOffset the offset in the reserved slot space
|
|
26553
|
+
* @param v1 1st argument to {@link PipeTransform#transform}.
|
|
26554
|
+
* @param v2 2nd argument to {@link PipeTransform#transform}.
|
|
26555
|
+
* @param v3 3rd argument to {@link PipeTransform#transform}.
|
|
26556
|
+
* @param v4 4th argument to {@link PipeTransform#transform}.
|
|
26557
|
+
*
|
|
26558
|
+
* @codeGenApi
|
|
26273
26559
|
*/
|
|
26274
|
-
function
|
|
26275
|
-
const
|
|
26276
|
-
|
|
26277
|
-
|
|
26278
|
-
|
|
26279
|
-
|
|
26280
|
-
// Verify whether the first dehydrated view in the container matches
|
|
26281
|
-
// the template id passed to this function (that originated from a TView
|
|
26282
|
-
// that was used to create an instance of an embedded or component views.
|
|
26283
|
-
if (view.data[TEMPLATE_ID] === template) {
|
|
26284
|
-
// If the template id matches - extract the first view and return it.
|
|
26285
|
-
return views.shift();
|
|
26286
|
-
}
|
|
26287
|
-
else {
|
|
26288
|
-
// Otherwise, we are at the state when reconciliation can not be completed,
|
|
26289
|
-
// thus we remove all dehydrated views within this container (remove them
|
|
26290
|
-
// from internal data structures as well as delete associated elements from
|
|
26291
|
-
// the DOM tree).
|
|
26292
|
-
removeDehydratedViews(lContainer);
|
|
26293
|
-
return null;
|
|
26294
|
-
}
|
|
26560
|
+
function ɵɵpipeBind4(index, slotOffset, v1, v2, v3, v4) {
|
|
26561
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26562
|
+
const lView = getLView();
|
|
26563
|
+
const pipeInstance = load(lView, adjustedIndex);
|
|
26564
|
+
return isPure(lView, adjustedIndex) ? pureFunction4Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) :
|
|
26565
|
+
pipeInstance.transform(v1, v2, v3, v4);
|
|
26295
26566
|
}
|
|
26296
|
-
|
|
26297
|
-
|
|
26567
|
+
/**
|
|
26568
|
+
* Invokes a pipe with variable number of arguments.
|
|
26569
|
+
*
|
|
26570
|
+
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
|
|
26571
|
+
* the pipe only when an input to the pipe changes.
|
|
26572
|
+
*
|
|
26573
|
+
* @param index Pipe index where the pipe was stored on creation.
|
|
26574
|
+
* @param slotOffset the offset in the reserved slot space
|
|
26575
|
+
* @param values Array of arguments to pass to {@link PipeTransform#transform} method.
|
|
26576
|
+
*
|
|
26577
|
+
* @codeGenApi
|
|
26578
|
+
*/
|
|
26579
|
+
function ɵɵpipeBindV(index, slotOffset, values) {
|
|
26580
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
26581
|
+
const lView = getLView();
|
|
26582
|
+
const pipeInstance = load(lView, adjustedIndex);
|
|
26583
|
+
return isPure(lView, adjustedIndex) ?
|
|
26584
|
+
pureFunctionVInternal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, values, pipeInstance) :
|
|
26585
|
+
pipeInstance.transform.apply(pipeInstance, values);
|
|
26298
26586
|
}
|
|
26299
|
-
function
|
|
26300
|
-
return
|
|
26587
|
+
function isPure(lView, index) {
|
|
26588
|
+
return lView[TVIEW].data[index].pure;
|
|
26301
26589
|
}
|
|
26302
26590
|
|
|
26591
|
+
function symbolIterator() {
|
|
26592
|
+
// @ts-expect-error accessing a private member
|
|
26593
|
+
return this._results[Symbol.iterator]();
|
|
26594
|
+
}
|
|
26303
26595
|
/**
|
|
26304
|
-
*
|
|
26596
|
+
* An unmodifiable list of items that Angular keeps up to date when the state
|
|
26597
|
+
* of the application changes.
|
|
26305
26598
|
*
|
|
26306
|
-
*
|
|
26307
|
-
*
|
|
26308
|
-
* (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
|
|
26599
|
+
* The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
|
|
26600
|
+
* provide.
|
|
26309
26601
|
*
|
|
26310
|
-
*
|
|
26311
|
-
*
|
|
26602
|
+
* Implements an iterable interface, therefore it can be used in both ES6
|
|
26603
|
+
* javascript `for (var i of items)` loops as well as in Angular templates with
|
|
26604
|
+
* `*ngFor="let i of myList"`.
|
|
26312
26605
|
*
|
|
26313
|
-
*
|
|
26314
|
-
*
|
|
26606
|
+
* Changes can be observed by subscribing to the changes `Observable`.
|
|
26607
|
+
*
|
|
26608
|
+
* NOTE: In the future this class will implement an `Observable` interface.
|
|
26609
|
+
*
|
|
26610
|
+
* @usageNotes
|
|
26611
|
+
* ### Example
|
|
26612
|
+
* ```typescript
|
|
26613
|
+
* @Component({...})
|
|
26614
|
+
* class Container {
|
|
26615
|
+
* @ViewChildren(Item) items:QueryList<Item>;
|
|
26616
|
+
* }
|
|
26617
|
+
* ```
|
|
26315
26618
|
*
|
|
26316
26619
|
* @publicApi
|
|
26317
26620
|
*/
|
|
26318
|
-
class
|
|
26621
|
+
class QueryList {
|
|
26622
|
+
static { Symbol.iterator; }
|
|
26319
26623
|
/**
|
|
26320
|
-
*
|
|
26321
|
-
* @nocollapse
|
|
26624
|
+
* Returns `Observable` of `QueryList` notifying the subscriber of changes.
|
|
26322
26625
|
*/
|
|
26323
|
-
|
|
26324
|
-
|
|
26325
|
-
/**
|
|
26326
|
-
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
|
|
26327
|
-
* already exists, retrieves the existing ViewContainerRef.
|
|
26328
|
-
*
|
|
26329
|
-
* @returns The ViewContainerRef instance to use
|
|
26330
|
-
*/
|
|
26331
|
-
function injectViewContainerRef() {
|
|
26332
|
-
const previousTNode = getCurrentTNode();
|
|
26333
|
-
return createContainerRef(previousTNode, getLView());
|
|
26334
|
-
}
|
|
26335
|
-
const VE_ViewContainerRef = ViewContainerRef;
|
|
26336
|
-
// TODO(alxhub): cleaning up this indirection triggers a subtle bug in Closure in g3. Once the fix
|
|
26337
|
-
// for that lands, this can be cleaned up.
|
|
26338
|
-
const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
26339
|
-
constructor(_lContainer, _hostTNode, _hostLView) {
|
|
26340
|
-
super();
|
|
26341
|
-
this._lContainer = _lContainer;
|
|
26342
|
-
this._hostTNode = _hostTNode;
|
|
26343
|
-
this._hostLView = _hostLView;
|
|
26344
|
-
}
|
|
26345
|
-
get element() {
|
|
26346
|
-
return createElementRef(this._hostTNode, this._hostLView);
|
|
26347
|
-
}
|
|
26348
|
-
get injector() {
|
|
26349
|
-
return new NodeInjector(this._hostTNode, this._hostLView);
|
|
26350
|
-
}
|
|
26351
|
-
/** @deprecated No replacement */
|
|
26352
|
-
get parentInjector() {
|
|
26353
|
-
const parentLocation = getParentInjectorLocation(this._hostTNode, this._hostLView);
|
|
26354
|
-
if (hasParentInjector(parentLocation)) {
|
|
26355
|
-
const parentView = getParentInjectorView(parentLocation, this._hostLView);
|
|
26356
|
-
const injectorIndex = getParentInjectorIndex(parentLocation);
|
|
26357
|
-
ngDevMode && assertNodeInjector(parentView, injectorIndex);
|
|
26358
|
-
const parentTNode = parentView[TVIEW].data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */];
|
|
26359
|
-
return new NodeInjector(parentTNode, parentView);
|
|
26360
|
-
}
|
|
26361
|
-
else {
|
|
26362
|
-
return new NodeInjector(null, this._hostLView);
|
|
26363
|
-
}
|
|
26626
|
+
get changes() {
|
|
26627
|
+
return this._changes || (this._changes = new EventEmitter());
|
|
26364
26628
|
}
|
|
26365
|
-
|
|
26366
|
-
|
|
26367
|
-
|
|
26368
|
-
|
|
26629
|
+
/**
|
|
26630
|
+
* @param emitDistinctChangesOnly Whether `QueryList.changes` should fire only when actual change
|
|
26631
|
+
* has occurred. Or if it should fire when query is recomputed. (recomputing could resolve in
|
|
26632
|
+
* the same result)
|
|
26633
|
+
*/
|
|
26634
|
+
constructor(_emitDistinctChangesOnly = false) {
|
|
26635
|
+
this._emitDistinctChangesOnly = _emitDistinctChangesOnly;
|
|
26636
|
+
this.dirty = true;
|
|
26637
|
+
this._results = [];
|
|
26638
|
+
this._changesDetected = false;
|
|
26639
|
+
this._changes = null;
|
|
26640
|
+
this.length = 0;
|
|
26641
|
+
this.first = undefined;
|
|
26642
|
+
this.last = undefined;
|
|
26643
|
+
// This function should be declared on the prototype, but doing so there will cause the class
|
|
26644
|
+
// declaration to have side-effects and become not tree-shakable. For this reason we do it in
|
|
26645
|
+
// the constructor.
|
|
26646
|
+
// [Symbol.iterator](): Iterator<T> { ... }
|
|
26647
|
+
const proto = QueryList.prototype;
|
|
26648
|
+
if (!proto[Symbol.iterator])
|
|
26649
|
+
proto[Symbol.iterator] = symbolIterator;
|
|
26369
26650
|
}
|
|
26651
|
+
/**
|
|
26652
|
+
* Returns the QueryList entry at `index`.
|
|
26653
|
+
*/
|
|
26370
26654
|
get(index) {
|
|
26371
|
-
|
|
26372
|
-
return viewRefs !== null && viewRefs[index] || null;
|
|
26373
|
-
}
|
|
26374
|
-
get length() {
|
|
26375
|
-
return this._lContainer.length - CONTAINER_HEADER_OFFSET;
|
|
26655
|
+
return this._results[index];
|
|
26376
26656
|
}
|
|
26377
|
-
|
|
26378
|
-
|
|
26379
|
-
|
|
26380
|
-
|
|
26381
|
-
|
|
26382
|
-
|
|
26383
|
-
else if (indexOrOptions != null) {
|
|
26384
|
-
index = indexOrOptions.index;
|
|
26385
|
-
injector = indexOrOptions.injector;
|
|
26386
|
-
}
|
|
26387
|
-
const hydrationInfo = findMatchingDehydratedView(this._lContainer, templateRef.ssrId);
|
|
26388
|
-
const viewRef = templateRef.createEmbeddedViewImpl(context || {}, injector, hydrationInfo);
|
|
26389
|
-
// If there is a matching dehydrated view, but the host TNode is located in the skip
|
|
26390
|
-
// hydration block, this means that the content was detached (as a part of the skip
|
|
26391
|
-
// hydration logic) and it needs to be appended into the DOM.
|
|
26392
|
-
const skipDomInsertion = !!hydrationInfo && !hasInSkipHydrationBlockFlag(this._hostTNode);
|
|
26393
|
-
this.insertImpl(viewRef, index, skipDomInsertion);
|
|
26394
|
-
return viewRef;
|
|
26657
|
+
/**
|
|
26658
|
+
* See
|
|
26659
|
+
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
|
|
26660
|
+
*/
|
|
26661
|
+
map(fn) {
|
|
26662
|
+
return this._results.map(fn);
|
|
26395
26663
|
}
|
|
26396
|
-
|
|
26397
|
-
|
|
26398
|
-
let index;
|
|
26399
|
-
// This function supports 2 signatures and we need to handle options correctly for both:
|
|
26400
|
-
// 1. When first argument is a Component type. This signature also requires extra
|
|
26401
|
-
// options to be provided as object (more ergonomic option).
|
|
26402
|
-
// 2. First argument is a Component factory. In this case extra options are represented as
|
|
26403
|
-
// positional arguments. This signature is less ergonomic and will be deprecated.
|
|
26404
|
-
if (isComponentFactory) {
|
|
26405
|
-
if (ngDevMode) {
|
|
26406
|
-
assertEqual(typeof indexOrOptions !== 'object', true, 'It looks like Component factory was provided as the first argument ' +
|
|
26407
|
-
'and an options object as the second argument. This combination of arguments ' +
|
|
26408
|
-
'is incompatible. You can either change the first argument to provide Component ' +
|
|
26409
|
-
'type or change the second argument to be a number (representing an index at ' +
|
|
26410
|
-
'which to insert the new component\'s host view into this container)');
|
|
26411
|
-
}
|
|
26412
|
-
index = indexOrOptions;
|
|
26413
|
-
}
|
|
26414
|
-
else {
|
|
26415
|
-
if (ngDevMode) {
|
|
26416
|
-
assertDefined(getComponentDef(componentFactoryOrType), `Provided Component class doesn't contain Component definition. ` +
|
|
26417
|
-
`Please check whether provided class has @Component decorator.`);
|
|
26418
|
-
assertEqual(typeof indexOrOptions !== 'number', true, 'It looks like Component type was provided as the first argument ' +
|
|
26419
|
-
'and a number (representing an index at which to insert the new component\'s ' +
|
|
26420
|
-
'host view into this container as the second argument. This combination of arguments ' +
|
|
26421
|
-
'is incompatible. Please use an object as the second argument instead.');
|
|
26422
|
-
}
|
|
26423
|
-
const options = (indexOrOptions || {});
|
|
26424
|
-
if (ngDevMode && options.environmentInjector && options.ngModuleRef) {
|
|
26425
|
-
throwError(`Cannot pass both environmentInjector and ngModuleRef options to createComponent().`);
|
|
26426
|
-
}
|
|
26427
|
-
index = options.index;
|
|
26428
|
-
injector = options.injector;
|
|
26429
|
-
projectableNodes = options.projectableNodes;
|
|
26430
|
-
environmentInjector = options.environmentInjector || options.ngModuleRef;
|
|
26431
|
-
}
|
|
26432
|
-
const componentFactory = isComponentFactory ?
|
|
26433
|
-
componentFactoryOrType :
|
|
26434
|
-
new ComponentFactory(getComponentDef(componentFactoryOrType));
|
|
26435
|
-
const contextInjector = injector || this.parentInjector;
|
|
26436
|
-
// If an `NgModuleRef` is not provided explicitly, try retrieving it from the DI tree.
|
|
26437
|
-
if (!environmentInjector && componentFactory.ngModule == null) {
|
|
26438
|
-
// For the `ComponentFactory` case, entering this logic is very unlikely, since we expect that
|
|
26439
|
-
// an instance of a `ComponentFactory`, resolved via `ComponentFactoryResolver` would have an
|
|
26440
|
-
// `ngModule` field. This is possible in some test scenarios and potentially in some JIT-based
|
|
26441
|
-
// use-cases. For the `ComponentFactory` case we preserve backwards-compatibility and try
|
|
26442
|
-
// using a provided injector first, then fall back to the parent injector of this
|
|
26443
|
-
// `ViewContainerRef` instance.
|
|
26444
|
-
//
|
|
26445
|
-
// For the factory-less case, it's critical to establish a connection with the module
|
|
26446
|
-
// injector tree (by retrieving an instance of an `NgModuleRef` and accessing its injector),
|
|
26447
|
-
// so that a component can use DI tokens provided in MgModules. For this reason, we can not
|
|
26448
|
-
// rely on the provided injector, since it might be detached from the DI tree (for example, if
|
|
26449
|
-
// it was created via `Injector.create` without specifying a parent injector, or if an
|
|
26450
|
-
// injector is retrieved from an `NgModuleRef` created via `createNgModule` using an
|
|
26451
|
-
// NgModule outside of a module tree). Instead, we always use `ViewContainerRef`'s parent
|
|
26452
|
-
// injector, which is normally connected to the DI tree, which includes module injector
|
|
26453
|
-
// subtree.
|
|
26454
|
-
const _injector = isComponentFactory ? contextInjector : this.parentInjector;
|
|
26455
|
-
// DO NOT REFACTOR. The code here used to have a `injector.get(NgModuleRef, null) ||
|
|
26456
|
-
// undefined` expression which seems to cause internal google apps to fail. This is documented
|
|
26457
|
-
// in the following internal bug issue: go/b/142967802
|
|
26458
|
-
const result = _injector.get(EnvironmentInjector, null);
|
|
26459
|
-
if (result) {
|
|
26460
|
-
environmentInjector = result;
|
|
26461
|
-
}
|
|
26462
|
-
}
|
|
26463
|
-
const componentDef = getComponentDef(componentFactory.componentType ?? {});
|
|
26464
|
-
const dehydratedView = findMatchingDehydratedView(this._lContainer, componentDef?.id ?? null);
|
|
26465
|
-
const rNode = dehydratedView?.firstChild ?? null;
|
|
26466
|
-
const componentRef = componentFactory.create(contextInjector, projectableNodes, rNode, environmentInjector);
|
|
26467
|
-
// If there is a matching dehydrated view, but the host TNode is located in the skip
|
|
26468
|
-
// hydration block, this means that the content was detached (as a part of the skip
|
|
26469
|
-
// hydration logic) and it needs to be appended into the DOM.
|
|
26470
|
-
const skipDomInsertion = !!dehydratedView && !hasInSkipHydrationBlockFlag(this._hostTNode);
|
|
26471
|
-
this.insertImpl(componentRef.hostView, index, skipDomInsertion);
|
|
26472
|
-
return componentRef;
|
|
26664
|
+
filter(fn) {
|
|
26665
|
+
return this._results.filter(fn);
|
|
26473
26666
|
}
|
|
26474
|
-
|
|
26475
|
-
|
|
26667
|
+
/**
|
|
26668
|
+
* See
|
|
26669
|
+
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
|
|
26670
|
+
*/
|
|
26671
|
+
find(fn) {
|
|
26672
|
+
return this._results.find(fn);
|
|
26476
26673
|
}
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
26481
|
-
|
|
26482
|
-
|
|
26483
|
-
if (viewAttachedToContainer(lView)) {
|
|
26484
|
-
// If view is already attached, detach it first so we clean up references appropriately.
|
|
26485
|
-
const prevIdx = this.indexOf(viewRef);
|
|
26486
|
-
// A view might be attached either to this or a different container. The `prevIdx` for
|
|
26487
|
-
// those cases will be:
|
|
26488
|
-
// equal to -1 for views attached to this ViewContainerRef
|
|
26489
|
-
// >= 0 for views attached to a different ViewContainerRef
|
|
26490
|
-
if (prevIdx !== -1) {
|
|
26491
|
-
this.detach(prevIdx);
|
|
26492
|
-
}
|
|
26493
|
-
else {
|
|
26494
|
-
const prevLContainer = lView[PARENT];
|
|
26495
|
-
ngDevMode &&
|
|
26496
|
-
assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.');
|
|
26497
|
-
// We need to re-create a R3ViewContainerRef instance since those are not stored on
|
|
26498
|
-
// LView (nor anywhere else).
|
|
26499
|
-
const prevVCRef = new R3ViewContainerRef(prevLContainer, prevLContainer[T_HOST], prevLContainer[PARENT]);
|
|
26500
|
-
prevVCRef.detach(prevVCRef.indexOf(viewRef));
|
|
26501
|
-
}
|
|
26502
|
-
}
|
|
26503
|
-
// Logical operation of adding `LView` to `LContainer`
|
|
26504
|
-
const adjustedIdx = this._adjustIndex(index);
|
|
26505
|
-
const lContainer = this._lContainer;
|
|
26506
|
-
addLViewToLContainer(lContainer, lView, adjustedIdx, !skipDomInsertion);
|
|
26507
|
-
viewRef.attachToViewContainerRef();
|
|
26508
|
-
addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
|
|
26509
|
-
return viewRef;
|
|
26674
|
+
/**
|
|
26675
|
+
* See
|
|
26676
|
+
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
|
|
26677
|
+
*/
|
|
26678
|
+
reduce(fn, init) {
|
|
26679
|
+
return this._results.reduce(fn, init);
|
|
26510
26680
|
}
|
|
26511
|
-
|
|
26512
|
-
|
|
26513
|
-
|
|
26514
|
-
|
|
26515
|
-
|
|
26681
|
+
/**
|
|
26682
|
+
* See
|
|
26683
|
+
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
|
|
26684
|
+
*/
|
|
26685
|
+
forEach(fn) {
|
|
26686
|
+
this._results.forEach(fn);
|
|
26516
26687
|
}
|
|
26517
|
-
|
|
26518
|
-
|
|
26519
|
-
|
|
26688
|
+
/**
|
|
26689
|
+
* See
|
|
26690
|
+
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
|
|
26691
|
+
*/
|
|
26692
|
+
some(fn) {
|
|
26693
|
+
return this._results.some(fn);
|
|
26520
26694
|
}
|
|
26521
|
-
|
|
26522
|
-
|
|
26523
|
-
|
|
26524
|
-
|
|
26525
|
-
|
|
26526
|
-
// This ensures the view container length is updated before calling
|
|
26527
|
-
// `destroyLView`, which could recursively call view container methods that
|
|
26528
|
-
// rely on an accurate container length.
|
|
26529
|
-
// (e.g. a method on this view container being called by a child directive's OnDestroy
|
|
26530
|
-
// lifecycle hook)
|
|
26531
|
-
removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx);
|
|
26532
|
-
destroyLView(detachedView[TVIEW], detachedView);
|
|
26533
|
-
}
|
|
26695
|
+
/**
|
|
26696
|
+
* Returns a copy of the internal results list as an Array.
|
|
26697
|
+
*/
|
|
26698
|
+
toArray() {
|
|
26699
|
+
return this._results.slice();
|
|
26534
26700
|
}
|
|
26535
|
-
|
|
26536
|
-
|
|
26537
|
-
const view = detachView(this._lContainer, adjustedIdx);
|
|
26538
|
-
const wasDetached = view && removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx) != null;
|
|
26539
|
-
return wasDetached ? new ViewRef$1(view) : null;
|
|
26701
|
+
toString() {
|
|
26702
|
+
return this._results.toString();
|
|
26540
26703
|
}
|
|
26541
|
-
|
|
26542
|
-
|
|
26543
|
-
|
|
26544
|
-
|
|
26545
|
-
|
|
26546
|
-
|
|
26547
|
-
|
|
26548
|
-
|
|
26704
|
+
/**
|
|
26705
|
+
* Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
|
|
26706
|
+
* on change detection, it will not notify of changes to the queries, unless a new change
|
|
26707
|
+
* occurs.
|
|
26708
|
+
*
|
|
26709
|
+
* @param resultsTree The query results to store
|
|
26710
|
+
* @param identityAccessor Optional function for extracting stable object identity from a value
|
|
26711
|
+
* in the array. This function is executed for each element of the query result list while
|
|
26712
|
+
* comparing current query list with the new one (provided as a first argument of the `reset`
|
|
26713
|
+
* function) to detect if the lists are different. If the function is not provided, elements
|
|
26714
|
+
* are compared as is (without any pre-processing).
|
|
26715
|
+
*/
|
|
26716
|
+
reset(resultsTree, identityAccessor) {
|
|
26717
|
+
// Cast to `QueryListInternal` so that we can mutate fields which are readonly for the usage of
|
|
26718
|
+
// QueryList (but not for QueryList itself.)
|
|
26719
|
+
const self = this;
|
|
26720
|
+
self.dirty = false;
|
|
26721
|
+
const newResultFlat = flatten(resultsTree);
|
|
26722
|
+
if (this._changesDetected = !arrayEquals(self._results, newResultFlat, identityAccessor)) {
|
|
26723
|
+
self._results = newResultFlat;
|
|
26724
|
+
self.length = newResultFlat.length;
|
|
26725
|
+
self.last = newResultFlat[this.length - 1];
|
|
26726
|
+
self.first = newResultFlat[0];
|
|
26549
26727
|
}
|
|
26550
|
-
return index;
|
|
26551
26728
|
}
|
|
26552
|
-
|
|
26553
|
-
|
|
26554
|
-
|
|
26555
|
-
|
|
26556
|
-
|
|
26557
|
-
|
|
26558
|
-
}
|
|
26559
|
-
/**
|
|
26560
|
-
* Creates a ViewContainerRef and stores it on the injector.
|
|
26561
|
-
*
|
|
26562
|
-
* @param hostTNode The node that is requesting a ViewContainerRef
|
|
26563
|
-
* @param hostLView The view to which the node belongs
|
|
26564
|
-
* @returns The ViewContainerRef instance to use
|
|
26565
|
-
*/
|
|
26566
|
-
function createContainerRef(hostTNode, hostLView) {
|
|
26567
|
-
ngDevMode && assertTNodeType(hostTNode, 12 /* TNodeType.AnyContainer */ | 3 /* TNodeType.AnyRNode */);
|
|
26568
|
-
let lContainer;
|
|
26569
|
-
const slotValue = hostLView[hostTNode.index];
|
|
26570
|
-
if (isLContainer(slotValue)) {
|
|
26571
|
-
// If the host is a container, we don't need to create a new LContainer
|
|
26572
|
-
lContainer = slotValue;
|
|
26729
|
+
/**
|
|
26730
|
+
* Triggers a change event by emitting on the `changes` {@link EventEmitter}.
|
|
26731
|
+
*/
|
|
26732
|
+
notifyOnChanges() {
|
|
26733
|
+
if (this._changes && (this._changesDetected || !this._emitDistinctChangesOnly))
|
|
26734
|
+
this._changes.emit(this);
|
|
26573
26735
|
}
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
26578
|
-
|
|
26579
|
-
|
|
26580
|
-
|
|
26736
|
+
/** internal */
|
|
26737
|
+
setDirty() {
|
|
26738
|
+
this.dirty = true;
|
|
26739
|
+
}
|
|
26740
|
+
/** internal */
|
|
26741
|
+
destroy() {
|
|
26742
|
+
this.changes.complete();
|
|
26743
|
+
this.changes.unsubscribe();
|
|
26581
26744
|
}
|
|
26582
|
-
_locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue);
|
|
26583
|
-
return new R3ViewContainerRef(lContainer, hostTNode, hostLView);
|
|
26584
26745
|
}
|
|
26746
|
+
|
|
26585
26747
|
/**
|
|
26586
|
-
*
|
|
26748
|
+
* Represents an embedded template that can be used to instantiate embedded views.
|
|
26749
|
+
* To instantiate embedded views based on a template, use the `ViewContainerRef`
|
|
26750
|
+
* method `createEmbeddedView()`.
|
|
26587
26751
|
*
|
|
26588
|
-
*
|
|
26589
|
-
*
|
|
26590
|
-
*
|
|
26752
|
+
* Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
|
|
26753
|
+
* element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
|
|
26754
|
+
* is injected into the constructor of the directive,
|
|
26755
|
+
* using the `TemplateRef` token.
|
|
26756
|
+
*
|
|
26757
|
+
* You can also use a `Query` to find a `TemplateRef` associated with
|
|
26758
|
+
* a component or a directive.
|
|
26759
|
+
*
|
|
26760
|
+
* @see {@link ViewContainerRef}
|
|
26761
|
+
* @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
|
|
26762
|
+
*
|
|
26763
|
+
* @publicApi
|
|
26591
26764
|
*/
|
|
26592
|
-
|
|
26593
|
-
|
|
26594
|
-
|
|
26595
|
-
|
|
26596
|
-
|
|
26597
|
-
|
|
26598
|
-
nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative), false);
|
|
26599
|
-
return commentNode;
|
|
26765
|
+
class TemplateRef {
|
|
26766
|
+
/**
|
|
26767
|
+
* @internal
|
|
26768
|
+
* @nocollapse
|
|
26769
|
+
*/
|
|
26770
|
+
static { this.__NG_ELEMENT_ID__ = injectTemplateRef; }
|
|
26600
26771
|
}
|
|
26601
|
-
|
|
26602
|
-
|
|
26603
|
-
|
|
26604
|
-
|
|
26605
|
-
|
|
26606
|
-
|
|
26607
|
-
|
|
26608
|
-
|
|
26609
|
-
|
|
26610
|
-
let commentNode;
|
|
26611
|
-
// If the host is an element container, the native host element is guaranteed to be a
|
|
26612
|
-
// comment and we can reuse that comment as anchor element for the new LContainer.
|
|
26613
|
-
// The comment node in question is already part of the DOM structure so we don't need to append
|
|
26614
|
-
// it again.
|
|
26615
|
-
if (hostTNode.type & 8 /* TNodeType.ElementContainer */) {
|
|
26616
|
-
commentNode = unwrapRNode(slotValue);
|
|
26772
|
+
const ViewEngineTemplateRef = TemplateRef;
|
|
26773
|
+
// TODO(alxhub): combine interface and implementation. Currently this is challenging since something
|
|
26774
|
+
// in g3 depends on them being separate.
|
|
26775
|
+
const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
|
|
26776
|
+
constructor(_declarationLView, _declarationTContainer, elementRef) {
|
|
26777
|
+
super();
|
|
26778
|
+
this._declarationLView = _declarationLView;
|
|
26779
|
+
this._declarationTContainer = _declarationTContainer;
|
|
26780
|
+
this.elementRef = elementRef;
|
|
26617
26781
|
}
|
|
26618
|
-
|
|
26619
|
-
|
|
26782
|
+
/**
|
|
26783
|
+
* Returns an `ssrId` associated with a TView, which was used to
|
|
26784
|
+
* create this instance of the `TemplateRef`.
|
|
26785
|
+
*
|
|
26786
|
+
* @internal
|
|
26787
|
+
*/
|
|
26788
|
+
get ssrId() {
|
|
26789
|
+
return this._declarationTContainer.tView?.ssrId || null;
|
|
26620
26790
|
}
|
|
26621
|
-
|
|
26791
|
+
createEmbeddedView(context, injector) {
|
|
26792
|
+
return this.createEmbeddedViewImpl(context, injector);
|
|
26793
|
+
}
|
|
26794
|
+
/**
|
|
26795
|
+
* @internal
|
|
26796
|
+
*/
|
|
26797
|
+
createEmbeddedViewImpl(context, injector, dehydratedView) {
|
|
26798
|
+
const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { injector, dehydratedView });
|
|
26799
|
+
return new ViewRef$1(embeddedLView);
|
|
26800
|
+
}
|
|
26801
|
+
};
|
|
26802
|
+
/**
|
|
26803
|
+
* Creates a TemplateRef given a node.
|
|
26804
|
+
*
|
|
26805
|
+
* @returns The TemplateRef instance to use
|
|
26806
|
+
*/
|
|
26807
|
+
function injectTemplateRef() {
|
|
26808
|
+
return createTemplateRef(getCurrentTNode(), getLView());
|
|
26622
26809
|
}
|
|
26623
26810
|
/**
|
|
26624
|
-
*
|
|
26625
|
-
*
|
|
26626
|
-
*
|
|
26811
|
+
* Creates a TemplateRef and stores it on the injector.
|
|
26812
|
+
*
|
|
26813
|
+
* @param hostTNode The node on which a TemplateRef is requested
|
|
26814
|
+
* @param hostLView The `LView` to which the node belongs
|
|
26815
|
+
* @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
|
|
26627
26816
|
*/
|
|
26628
|
-
function
|
|
26629
|
-
|
|
26630
|
-
|
|
26631
|
-
|
|
26632
|
-
if (lContainer[NATIVE] && lContainer[DEHYDRATED_VIEWS])
|
|
26633
|
-
return;
|
|
26634
|
-
const hydrationInfo = hostLView[HYDRATION];
|
|
26635
|
-
const noOffsetIndex = hostTNode.index - HEADER_OFFSET;
|
|
26636
|
-
// TODO(akushnir): this should really be a single condition, refactor the code
|
|
26637
|
-
// to use `hasInSkipHydrationBlockFlag` logic inside `isInSkipHydrationBlock`.
|
|
26638
|
-
const skipHydration = isInSkipHydrationBlock(hostTNode) || hasInSkipHydrationBlockFlag(hostTNode);
|
|
26639
|
-
const isNodeCreationMode = !hydrationInfo || skipHydration || isDisconnectedNode$1(hydrationInfo, noOffsetIndex);
|
|
26640
|
-
// Regular creation mode.
|
|
26641
|
-
if (isNodeCreationMode) {
|
|
26642
|
-
return createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
|
|
26643
|
-
}
|
|
26644
|
-
// Hydration mode, looking up an anchor node and dehydrated views in DOM.
|
|
26645
|
-
const currentRNode = getSegmentHead(hydrationInfo, noOffsetIndex);
|
|
26646
|
-
const serializedViews = hydrationInfo.data[CONTAINERS]?.[noOffsetIndex];
|
|
26647
|
-
ngDevMode &&
|
|
26648
|
-
assertDefined(serializedViews, 'Unexpected state: no hydration info available for a given TNode, ' +
|
|
26649
|
-
'which represents a view container.');
|
|
26650
|
-
const [commentNode, dehydratedViews] = locateDehydratedViewsInContainer(currentRNode, serializedViews);
|
|
26651
|
-
if (ngDevMode) {
|
|
26652
|
-
validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode, true);
|
|
26653
|
-
// Do not throw in case this node is already claimed (thus `false` as a second
|
|
26654
|
-
// argument). If this container is created based on an `<ng-template>`, the comment
|
|
26655
|
-
// node would be already claimed from the `template` instruction. If an element acts
|
|
26656
|
-
// as an anchor (e.g. <div #vcRef>), a separate comment node would be created/located,
|
|
26657
|
-
// so we need to claim it here.
|
|
26658
|
-
markRNodeAsClaimedByHydration(commentNode, false);
|
|
26817
|
+
function createTemplateRef(hostTNode, hostLView) {
|
|
26818
|
+
if (hostTNode.type & 4 /* TNodeType.Container */) {
|
|
26819
|
+
ngDevMode && assertDefined(hostTNode.tView, 'TView must be allocated');
|
|
26820
|
+
return new R3TemplateRef(hostLView, hostTNode, createElementRef(hostTNode, hostLView));
|
|
26659
26821
|
}
|
|
26660
|
-
|
|
26661
|
-
lContainer[DEHYDRATED_VIEWS] = dehydratedViews;
|
|
26662
|
-
}
|
|
26663
|
-
function enableLocateOrCreateContainerRefImpl() {
|
|
26664
|
-
_locateOrCreateAnchorNode = locateOrCreateAnchorNode;
|
|
26822
|
+
return null;
|
|
26665
26823
|
}
|
|
26666
26824
|
|
|
26667
26825
|
class LQuery_ {
|
|
@@ -27279,6 +27437,7 @@ const angularCoreEnv = (() => ({
|
|
|
27279
27437
|
'ɵɵrepeaterCreate': ɵɵrepeaterCreate,
|
|
27280
27438
|
'ɵɵrepeaterTrackByIndex': ɵɵrepeaterTrackByIndex,
|
|
27281
27439
|
'ɵɵrepeaterTrackByIdentity': ɵɵrepeaterTrackByIdentity,
|
|
27440
|
+
'ɵɵcomponentInstance': ɵɵcomponentInstance,
|
|
27282
27441
|
'ɵɵtext': ɵɵtext,
|
|
27283
27442
|
'ɵɵtextInterpolate': ɵɵtextInterpolate,
|
|
27284
27443
|
'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
|
|
@@ -31891,11 +32050,13 @@ function serializeLView(lView, context) {
|
|
|
31891
32050
|
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
31892
32051
|
const tNode = tView.data[i];
|
|
31893
32052
|
const noOffsetIndex = i - HEADER_OFFSET;
|
|
31894
|
-
//
|
|
31895
|
-
//
|
|
31896
|
-
//
|
|
31897
|
-
//
|
|
31898
|
-
|
|
32053
|
+
// Skip processing of a given slot in the following cases:
|
|
32054
|
+
// - Local refs (e.g. <div #localRef>) take up an extra slot in LViews
|
|
32055
|
+
// to store the same element. In this case, there is no information in
|
|
32056
|
+
// a corresponding slot in TNode data structure.
|
|
32057
|
+
// - When a slot contains something other than a TNode. For example, there
|
|
32058
|
+
// might be some metadata information about a defer block or a control flow block.
|
|
32059
|
+
if (!isTNodeShape(tNode)) {
|
|
31899
32060
|
continue;
|
|
31900
32061
|
}
|
|
31901
32062
|
// Check if a native node that represents a given TNode is disconnected from the DOM tree.
|
|
@@ -32494,17 +32655,18 @@ function ɵɵngDeclarePipe(decl) {
|
|
|
32494
32655
|
* const applicationRef = await bootstrapApplication(RootComponent);
|
|
32495
32656
|
*
|
|
32496
32657
|
* // Locate a DOM node that would be used as a host.
|
|
32497
|
-
* const
|
|
32658
|
+
* const hostElement = document.getElementById('hello-component-host');
|
|
32498
32659
|
*
|
|
32499
32660
|
* // Get an `EnvironmentInjector` instance from the `ApplicationRef`.
|
|
32500
32661
|
* const environmentInjector = applicationRef.injector;
|
|
32501
32662
|
*
|
|
32502
32663
|
* // We can now create a `ComponentRef` instance.
|
|
32503
|
-
* const componentRef = createComponent(HelloComponent, {
|
|
32664
|
+
* const componentRef = createComponent(HelloComponent, {hostElement, environmentInjector});
|
|
32504
32665
|
*
|
|
32505
32666
|
* // Last step is to register the newly created ref using the `ApplicationRef` instance
|
|
32506
32667
|
* // to include the component view into change detection cycles.
|
|
32507
32668
|
* applicationRef.attachView(componentRef.hostView);
|
|
32669
|
+
* componentRef.changeDetectorRef.detectChanges();
|
|
32508
32670
|
* ```
|
|
32509
32671
|
*
|
|
32510
32672
|
* @param component Component class reference.
|
|
@@ -32647,5 +32809,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
32647
32809
|
* Generated bundle index. Do not edit.
|
|
32648
32810
|
*/
|
|
32649
32811
|
|
|
32650
|
-
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, USE_RUNTIME_DEPS_TRACKER_FOR_JIT as ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, depsTracker as ɵdepsTracker, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, getAsyncClassMetadata as ɵgetAsyncClassMetadata, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isComponentDefPendingResolution as ɵisComponentDefPendingResolution, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setClassMetadataAsync as ɵsetClassMetadataAsync, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵconditional, ɵɵcontentQuery, ɵɵdefer, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
|
|
32812
|
+
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, USE_RUNTIME_DEPS_TRACKER_FOR_JIT as ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, depsTracker as ɵdepsTracker, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, getAsyncClassMetadata as ɵgetAsyncClassMetadata, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isComponentDefPendingResolution as ɵisComponentDefPendingResolution, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setClassMetadataAsync as ɵsetClassMetadataAsync, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵcontentQuery, ɵɵdefer, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
|
|
32651
32813
|
//# sourceMappingURL=core.mjs.map
|