rdesign/frontend/node_modules/@lit/context/development/lib/controllers/context-consumer.js

83 lines
3.3 KiB
JavaScript

/**
* @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