UNPKG

@angular/core

Version:

Angular - the core framework

96 lines 13.2 kB
/** * @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