@angular/core
Version:
Angular - the core framework
96 lines • 13.2 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { REACTIVE_NODE } from '@angular/core/primitives/signals';
import { REACTIVE_TEMPLATE_CONSUMER, TVIEW, } from './interfaces/view';
import { getLViewParent, markAncestorsForTraversal, markViewForRefresh } from './util/view_utils';
let freeConsumers = [];
/**
* Create a new template consumer pointing at the specified LView.
* Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
* case, the LView will be updated.
*/
export function getOrBorrowReactiveLViewConsumer(lView) {
return lView[REACTIVE_TEMPLATE_CONSUMER] ?? borrowReactiveLViewConsumer(lView);
}
function borrowReactiveLViewConsumer(lView) {
const consumer = freeConsumers.pop() ?? Object.create(REACTIVE_LVIEW_CONSUMER_NODE);
consumer.lView = lView;
return consumer;
}
export function maybeReturnReactiveLViewConsumer(consumer) {
if (consumer.lView[REACTIVE_TEMPLATE_CONSUMER] === consumer) {
// The consumer got committed.
return;
}
consumer.lView = null;
freeConsumers.push(consumer);
}
const REACTIVE_LVIEW_CONSUMER_NODE = {
...REACTIVE_NODE,
consumerIsAlwaysLive: true,
consumerMarkedDirty: (node) => {
markAncestorsForTraversal(node.lView);
},
consumerOnSignalRead() {
this.lView[REACTIVE_TEMPLATE_CONSUMER] = this;
},
};
/**
* Creates a temporary consumer for use with `LView`s that should not have consumers.
* If the LView already has a consumer, returns the existing one instead.
*
* This is necessary because some APIs may cause change detection directly on an LView
* that we do not want to have a consumer (Embedded views today). As a result, there
* would be no active consumer from running change detection on its host component
* and any signals in the LView template would be untracked. Instead, we create
* this temporary consumer that marks the first parent that _should_ have a consumer
* for refresh. Once change detection runs as part of that refresh, we throw away
* this consumer because its signals will then be tracked by the parent's consumer.
*/
export function getOrCreateTemporaryConsumer(lView) {
const consumer = lView[REACTIVE_TEMPLATE_CONSUMER] ?? Object.create(TEMPORARY_CONSUMER_NODE);
consumer.lView = lView;
return consumer;
}
const TEMPORARY_CONSUMER_NODE = {
...REACTIVE_NODE,
consumerIsAlwaysLive: true,
consumerMarkedDirty: (node) => {
let parent = getLViewParent(node.lView);
while (parent && !viewShouldHaveReactiveConsumer(parent[TVIEW])) {
parent = getLViewParent(parent);
}
if (!parent) {
// If we can't find an appropriate parent that should have a consumer, we
// don't have a way of appropriately refreshing this LView as part of application synchronization.
return;
}
markViewForRefresh(parent);
},
consumerOnSignalRead() {
this.lView[REACTIVE_TEMPLATE_CONSUMER] = this;
},
};
/**
* Indicates if the view should get its own reactive consumer node.
*
* In the current design, all embedded views share a consumer with the component view. This allows
* us to refresh at the component level rather than at a per-view level. In addition, root views get
* their own reactive node because root component will have a host view that executes the
* component's host bindings. This needs to be tracked in a consumer as well.
*
* To get a more granular change detection than per-component, all we would just need to update the
* condition here so that a given view gets a reactive consumer which can become dirty independently
* from its parent component. For example embedded views for signal components could be created with
* a new type "SignalEmbeddedView" and the condition here wouldn't even need updating in order to
* get granular per-view change detection for signal components.
*/
export function viewShouldHaveReactiveConsumer(tView) {
return tView.type !== 2 /* TViewType.Embedded */;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3RpdmVfbHZpZXdfY29uc3VtZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3JlYWN0aXZlX2x2aWV3X2NvbnN1bWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxhQUFhLEVBQWUsTUFBTSxrQ0FBa0MsQ0FBQztBQUU3RSxPQUFPLEVBR0wsMEJBQTBCLEVBQzFCLEtBQUssR0FHTixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBQyxjQUFjLEVBQUUseUJBQXlCLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUdoRyxJQUFJLGFBQWEsR0FBbUIsRUFBRSxDQUFDO0FBS3ZDOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0NBQWdDLENBQUMsS0FBWTtJQUMzRCxPQUFPLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pGLENBQUM7QUFFRCxTQUFTLDJCQUEyQixDQUFDLEtBQVk7SUFDL0MsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLEdBQUcsRUFBRSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUNwRixRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUN2QixPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSxVQUFVLGdDQUFnQyxDQUFDLFFBQStCO0lBQzlFLElBQUksUUFBUSxDQUFDLEtBQU0sQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzdELDhCQUE4QjtRQUM5QixPQUFPO0lBQ1QsQ0FBQztJQUNELFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVELE1BQU0sNEJBQTRCLEdBQXlDO0lBQ3pFLEdBQUcsYUFBYTtJQUNoQixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLG1CQUFtQixFQUFFLENBQUMsSUFBMkIsRUFBRSxFQUFFO1FBQ25ELHlCQUF5QixDQUFDLElBQUksQ0FBQyxLQUFNLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0Qsb0JBQW9CO1FBQ2xCLElBQUksQ0FBQyxLQUFNLENBQUMsMEJBQTBCLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDakQsQ0FBQztDQUNGLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxLQUFZO0lBQ3ZELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUM3RixRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUN2QixPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSx1QkFBdUIsR0FBRztJQUM5QixHQUFHLGFBQWE7SUFDaEIsb0JBQW9CLEVBQUUsSUFBSTtJQUMxQixtQkFBbUIsRUFBRSxDQUFDLElBQTJCLEVBQUUsRUFBRTtRQUNuRCxJQUFJLE1BQU0sR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQU0sQ0FBQyxDQUFDO1FBQ3pDLE9BQU8sTUFBTSxJQUFJLENBQUMsOEJBQThCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNoRSxNQUFNLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWix5RUFBeUU7WUFDekUsa0dBQWtHO1lBQ2xHLE9BQU87UUFDVCxDQUFDO1FBRUQsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELG9CQUFvQjtRQUNsQixJQUFJLENBQUMsS0FBTSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQ2pELENBQUM7Q0FDRixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sVUFBVSw4QkFBOEIsQ0FBQyxLQUFZO0lBQ3pELE9BQU8sS0FBSyxDQUFDLElBQUksK0JBQXVCLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1JFQUNUSVZFX05PREUsIFJlYWN0aXZlTm9kZX0gZnJvbSAnQGFuZ3VsYXIvY29yZS9wcmltaXRpdmVzL3NpZ25hbHMnO1xuXG5pbXBvcnQge1xuICBMVmlldyxcbiAgUEFSRU5ULFxuICBSRUFDVElWRV9URU1QTEFURV9DT05TVU1FUixcbiAgVFZJRVcsXG4gIFRWaWV3LFxuICBUVmlld1R5cGUsXG59IGZyb20gJy4vaW50ZXJmYWNlcy92aWV3JztcbmltcG9ydCB7Z2V0TFZpZXdQYXJlbnQsIG1hcmtBbmNlc3RvcnNGb3JUcmF2ZXJzYWwsIG1hcmtWaWV3Rm9yUmVmcmVzaH0gZnJvbSAnLi91dGlsL3ZpZXdfdXRpbHMnO1xuaW1wb3J0IHthc3NlcnREZWZpbmVkfSBmcm9tICcuLi91dGlsL2Fzc2VydCc7XG5cbmxldCBmcmVlQ29uc3VtZXJzOiBSZWFjdGl2ZU5vZGVbXSA9IFtdO1xuZXhwb3J0IGludGVyZmFjZSBSZWFjdGl2ZUxWaWV3Q29uc3VtZXIgZXh0ZW5kcyBSZWFjdGl2ZU5vZGUge1xuICBsVmlldzogTFZpZXcgfCBudWxsO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyB0ZW1wbGF0ZSBjb25zdW1lciBwb2ludGluZyBhdCB0aGUgc3BlY2lmaWVkIExWaWV3LlxuICogU29tZXRpbWVzLCBhIHByZXZpb3VzbHkgY3JlYXRlZCBjb25zdW1lciBtYXkgYmUgcmV1c2VkLCBpbiBvcmRlciB0byBzYXZlIG9uIGFsbG9jYXRpb25zLiBJbiB0aGF0XG4gKiBjYXNlLCB0aGUgTFZpZXcgd2lsbCBiZSB1cGRhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JCb3Jyb3dSZWFjdGl2ZUxWaWV3Q29uc3VtZXIobFZpZXc6IExWaWV3KTogUmVhY3RpdmVMVmlld0NvbnN1bWVyIHtcbiAgcmV0dXJuIGxWaWV3W1JFQUNUSVZFX1RFTVBMQVRFX0NPTlNVTUVSXSA/PyBib3Jyb3dSZWFjdGl2ZUxWaWV3Q29uc3VtZXIobFZpZXcpO1xufVxuXG5mdW5jdGlvbiBib3Jyb3dSZWFjdGl2ZUxWaWV3Q29uc3VtZXIobFZpZXc6IExWaWV3KTogUmVhY3RpdmVMVmlld0NvbnN1bWVyIHtcbiAgY29uc3QgY29uc3VtZXIgPSBmcmVlQ29uc3VtZXJzLnBvcCgpID8/IE9iamVjdC5jcmVhdGUoUkVBQ1RJVkVfTFZJRVdfQ09OU1VNRVJfTk9ERSk7XG4gIGNvbnN1bWVyLmxWaWV3ID0gbFZpZXc7XG4gIHJldHVybiBjb25zdW1lcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUmV0dXJuUmVhY3RpdmVMVmlld0NvbnN1bWVyKGNvbnN1bWVyOiBSZWFjdGl2ZUxWaWV3Q29uc3VtZXIpOiB2b2lkIHtcbiAgaWYgKGNvbnN1bWVyLmxWaWV3IVtSRUFDVElWRV9URU1QTEFURV9DT05TVU1FUl0gPT09IGNvbnN1bWVyKSB7XG4gICAgLy8gVGhlIGNvbnN1bWVyIGdvdCBjb21taXR0ZWQuXG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN1bWVyLmxWaWV3ID0gbnVsbDtcbiAgZnJlZUNvbnN1bWVycy5wdXNoKGNvbnN1bWVyKTtcbn1cblxuY29uc3QgUkVBQ1RJVkVfTFZJRVdfQ09OU1VNRVJfTk9ERTogT21pdDxSZWFjdGl2ZUxWaWV3Q29uc3VtZXIsICdsVmlldyc+ID0ge1xuICAuLi5SRUFDVElWRV9OT0RFLFxuICBjb25zdW1lcklzQWx3YXlzTGl2ZTogdHJ1ZSxcbiAgY29uc3VtZXJNYXJrZWREaXJ0eTogKG5vZGU6IFJlYWN0aXZlTFZpZXdDb25zdW1lcikgPT4ge1xuICAgIG1hcmtBbmNlc3RvcnNGb3JUcmF2ZXJzYWwobm9kZS5sVmlldyEpO1xuICB9LFxuICBjb25zdW1lck9uU2lnbmFsUmVhZCh0aGlzOiBSZWFjdGl2ZUxWaWV3Q29uc3VtZXIpOiB2b2lkIHtcbiAgICB0aGlzLmxWaWV3IVtSRUFDVElWRV9URU1QTEFURV9DT05TVU1FUl0gPSB0aGlzO1xuICB9LFxufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgdGVtcG9yYXJ5IGNvbnN1bWVyIGZvciB1c2Ugd2l0aCBgTFZpZXdgcyB0aGF0IHNob3VsZCBub3QgaGF2ZSBjb25zdW1lcnMuXG4gKiBJZiB0aGUgTFZpZXcgYWxyZWFkeSBoYXMgYSBjb25zdW1lciwgcmV0dXJucyB0aGUgZXhpc3Rpbmcgb25lIGluc3RlYWQuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzb21lIEFQSXMgbWF5IGNhdXNlIGNoYW5nZSBkZXRlY3Rpb24gZGlyZWN0bHkgb24gYW4gTFZpZXdcbiAqIHRoYXQgd2UgZG8gbm90IHdhbnQgdG8gaGF2ZSBhIGNvbnN1bWVyIChFbWJlZGRlZCB2aWV3cyB0b2RheSkuIEFzIGEgcmVzdWx0LCB0aGVyZVxuICogd291bGQgYmUgbm8gYWN0aXZlIGNvbnN1bWVyIGZyb20gcnVubmluZyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIGl0cyBob3N0IGNvbXBvbmVudFxuICogYW5kIGFueSBzaWduYWxzIGluIHRoZSBMVmlldyB0ZW1wbGF0ZSB3b3VsZCBiZSB1bnRyYWNrZWQuIEluc3RlYWQsIHdlIGNyZWF0ZVxuICogdGhpcyB0ZW1wb3JhcnkgY29uc3VtZXIgdGhhdCBtYXJrcyB0aGUgZmlyc3QgcGFyZW50IHRoYXQgX3Nob3VsZF8gaGF2ZSBhIGNvbnN1bWVyXG4gKiBmb3IgcmVmcmVzaC4gT25jZSBjaGFuZ2UgZGV0ZWN0aW9uIHJ1bnMgYXMgcGFydCBvZiB0aGF0IHJlZnJlc2gsIHdlIHRocm93IGF3YXlcbiAqIHRoaXMgY29uc3VtZXIgYmVjYXVzZSBpdHMgc2lnbmFscyB3aWxsIHRoZW4gYmUgdHJhY2tlZCBieSB0aGUgcGFyZW50J3MgY29uc3VtZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPckNyZWF0ZVRlbXBvcmFyeUNvbnN1bWVyKGxWaWV3OiBMVmlldyk6IFJlYWN0aXZlTFZpZXdDb25zdW1lciB7XG4gIGNvbnN0IGNvbnN1bWVyID0gbFZpZXdbUkVBQ1RJVkVfVEVNUExBVEVfQ09OU1VNRVJdID8/IE9iamVjdC5jcmVhdGUoVEVNUE9SQVJZX0NPTlNVTUVSX05PREUpO1xuICBjb25zdW1lci5sVmlldyA9IGxWaWV3O1xuICByZXR1cm4gY29uc3VtZXI7XG59XG5cbmNvbnN0IFRFTVBPUkFSWV9DT05TVU1FUl9OT0RFID0ge1xuICAuLi5SRUFDVElWRV9OT0RFLFxuICBjb25zdW1lcklzQWx3YXlzTGl2ZTogdHJ1ZSxcbiAgY29uc3VtZXJNYXJrZWREaXJ0eTogKG5vZGU6IFJlYWN0aXZlTFZpZXdDb25zdW1lcikgPT4ge1xuICAgIGxldCBwYXJlbnQgPSBnZXRMVmlld1BhcmVudChub2RlLmxWaWV3ISk7XG4gICAgd2hpbGUgKHBhcmVudCAmJiAhdmlld1Nob3VsZEhhdmVSZWFjdGl2ZUNvbnN1bWVyKHBhcmVudFtUVklFV10pKSB7XG4gICAgICBwYXJlbnQgPSBnZXRMVmlld1BhcmVudChwYXJlbnQpO1xuICAgIH1cbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBhbiBhcHByb3ByaWF0ZSBwYXJlbnQgdGhhdCBzaG91bGQgaGF2ZSBhIGNvbnN1bWVyLCB3ZVxuICAgICAgLy8gZG9uJ3QgaGF2ZSBhIHdheSBvZiBhcHByb3ByaWF0ZWx5IHJlZnJlc2hpbmcgdGhpcyBMVmlldyBhcyBwYXJ0IG9mIGFwcGxpY2F0aW9uIHN5bmNocm9uaXphdGlvbi5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtYXJrVmlld0ZvclJlZnJlc2gocGFyZW50KTtcbiAgfSxcbiAgY29uc3VtZXJPblNpZ25hbFJlYWQodGhpczogUmVhY3RpdmVMVmlld0NvbnN1bWVyKTogdm9pZCB7XG4gICAgdGhpcy5sVmlldyFbUkVBQ1RJVkVfVEVNUExBVEVfQ09OU1VNRVJdID0gdGhpcztcbiAgfSxcbn07XG5cbi8qKlxuICogSW5kaWNhdGVzIGlmIHRoZSB2aWV3IHNob3VsZCBnZXQgaXRzIG93biByZWFjdGl2ZSBjb25zdW1lciBub2RlLlxuICpcbiAqIEluIHRoZSBjdXJyZW50IGRlc2lnbiwgYWxsIGVtYmVkZGVkIHZpZXdzIHNoYXJlIGEgY29uc3VtZXIgd2l0aCB0aGUgY29tcG9uZW50IHZpZXcuIFRoaXMgYWxsb3dzXG4gKiB1cyB0byByZWZyZXNoIGF0IHRoZSBjb21wb25lbnQgbGV2ZWwgcmF0aGVyIHRoYW4gYXQgYSBwZXItdmlldyBsZXZlbC4gSW4gYWRkaXRpb24sIHJvb3Qgdmlld3MgZ2V0XG4gKiB0aGVpciBvd24gcmVhY3RpdmUgbm9kZSBiZWNhdXNlIHJvb3QgY29tcG9uZW50IHdpbGwgaGF2ZSBhIGhvc3QgdmlldyB0aGF0IGV4ZWN1dGVzIHRoZVxuICogY29tcG9uZW50J3MgaG9zdCBiaW5kaW5ncy4gVGhpcyBuZWVkcyB0byBiZSB0cmFja2VkIGluIGEgY29uc3VtZXIgYXMgd2VsbC5cbiAqXG4gKiBUbyBnZXQgYSBtb3JlIGdyYW51bGFyIGNoYW5nZSBkZXRlY3Rpb24gdGhhbiBwZXItY29tcG9uZW50LCBhbGwgd2Ugd291bGQganVzdCBuZWVkIHRvIHVwZGF0ZSB0aGVcbiAqIGNvbmRpdGlvbiBoZXJlIHNvIHRoYXQgYSBnaXZlbiB2aWV3IGdldHMgYSByZWFjdGl2ZSBjb25zdW1lciB3aGljaCBjYW4gYmVjb21lIGRpcnR5IGluZGVwZW5kZW50bHlcbiAqIGZyb20gaXRzIHBhcmVudCBjb21wb25lbnQuIEZvciBleGFtcGxlIGVtYmVkZGVkIHZpZXdzIGZvciBzaWduYWwgY29tcG9uZW50cyBjb3VsZCBiZSBjcmVhdGVkIHdpdGhcbiAqIGEgbmV3IHR5cGUgXCJTaWduYWxFbWJlZGRlZFZpZXdcIiBhbmQgdGhlIGNvbmRpdGlvbiBoZXJlIHdvdWxkbid0IGV2ZW4gbmVlZCB1cGRhdGluZyBpbiBvcmRlciB0b1xuICogZ2V0IGdyYW51bGFyIHBlci12aWV3IGNoYW5nZSBkZXRlY3Rpb24gZm9yIHNpZ25hbCBjb21wb25lbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmlld1Nob3VsZEhhdmVSZWFjdGl2ZUNvbnN1bWVyKHRWaWV3OiBUVmlldykge1xuICByZXR1cm4gdFZpZXcudHlwZSAhPT0gVFZpZXdUeXBlLkVtYmVkZGVkO1xufVxuIl19