/** * @license * Copyright 2021 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ import { ContextRequestEvent, } from '../context-request-event.js'; /** * A ReactiveController which adds context consuming behavior to a custom * element by dispatching `context-request` events. * * When the host element is connected to the document it will emit a * `context-request` event with its context key. When the context request * is satisfied the controller will invoke the callback, if present, and * trigger a host update so it can respond to the new value. * * It will also call the dispose method given by the provider when the * host element is disconnected. */ export class ContextConsumer { constructor(host, contextOrOptions, callback, subscribe) { this.subscribe = false; this.provided = false; this.value = undefined; // This function must have stable identity to properly dedupe in ContextRoot // if this element connects multiple times. this._callback = (value, unsubscribe) => { // some providers will pass an unsubscribe function indicating they may provide future values if (this.unsubscribe) { // if the unsubscribe function changes this implies we have changed provider if (this.unsubscribe !== unsubscribe) { // cleanup the old provider this.provided = false; this.unsubscribe(); } // if we don't support subscription, immediately unsubscribe if (!this.subscribe) { this.unsubscribe(); } } // store the value so that it can be retrieved from the controller this.value = value; // schedule an update in case this value is used in a template this.host.requestUpdate(); // only invoke callback if we are either expecting updates or have not yet // been provided a value if (!this.provided || this.subscribe) { this.provided = true; if (this.callback) { this.callback(value, unsubscribe); } } this.unsubscribe = unsubscribe; }; this.host = host; // This is a potentially fragile duck-type. It means a context object can't // have a property name context and be used in positional argument form. if (contextOrOptions.context !== undefined) { const options = contextOrOptions; this.context = options.context; this.callback = options.callback; this.subscribe = options.subscribe ?? false; } else { this.context = contextOrOptions; this.callback = callback; this.subscribe = subscribe ?? false; } this.host.addController(this); } hostConnected() { this.dispatchRequest(); } hostDisconnected() { if (this.unsubscribe) { this.unsubscribe(); this.unsubscribe = undefined; } } dispatchRequest() { this.host.dispatchEvent(new ContextRequestEvent(this.context, this.host, this._callback, this.subscribe)); } } //# sourceMappingURL=context-consumer.js.map