first commit
This commit is contained in:
248
node_modules/lit-html/node/development/async-directive.js
generated
vendored
Normal file
248
node_modules/lit-html/node/development/async-directive.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
import { isSingleExpression } from './directive-helpers.js';
|
||||
import { Directive, PartType } from './directive.js';
|
||||
export { Directive, PartType, directive } from './directive.js';
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* Recursively walks down the tree of Parts/TemplateInstances/Directives to set
|
||||
* the connected state of directives and run `disconnected`/ `reconnected`
|
||||
* callbacks.
|
||||
*
|
||||
* @return True if there were children to disconnect; false otherwise
|
||||
*/
|
||||
const notifyChildrenConnectedChanged = (parent, isConnected) => {
|
||||
var _a, _b;
|
||||
const children = parent._$disconnectableChildren;
|
||||
if (children === undefined) {
|
||||
return false;
|
||||
}
|
||||
for (const obj of children) {
|
||||
// The existence of `_$notifyDirectiveConnectionChanged` is used as a "brand" to
|
||||
// disambiguate AsyncDirectives from other DisconnectableChildren
|
||||
// (as opposed to using an instanceof check to know when to call it); the
|
||||
// redundancy of "Directive" in the API name is to avoid conflicting with
|
||||
// `_$notifyConnectionChanged`, which exists `ChildParts` which are also in
|
||||
// this list
|
||||
// Disconnect Directive (and any nested directives contained within)
|
||||
// This property needs to remain unminified.
|
||||
(_b = (_a = obj)['_$notifyDirectiveConnectionChanged']) === null || _b === void 0 ? void 0 : _b.call(_a, isConnected, false);
|
||||
// Disconnect Part/TemplateInstance
|
||||
notifyChildrenConnectedChanged(obj, isConnected);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Removes the given child from its parent list of disconnectable children, and
|
||||
* if the parent list becomes empty as a result, removes the parent from its
|
||||
* parent, and so forth up the tree when that causes subsequent parent lists to
|
||||
* become empty.
|
||||
*/
|
||||
const removeDisconnectableFromParent = (obj) => {
|
||||
let parent, children;
|
||||
do {
|
||||
if ((parent = obj._$parent) === undefined) {
|
||||
break;
|
||||
}
|
||||
children = parent._$disconnectableChildren;
|
||||
children.delete(obj);
|
||||
obj = parent;
|
||||
} while ((children === null || children === void 0 ? void 0 : children.size) === 0);
|
||||
};
|
||||
const addDisconnectableToParent = (obj) => {
|
||||
// Climb the parent tree, creating a sparse tree of children needing
|
||||
// disconnection
|
||||
for (let parent; (parent = obj._$parent); obj = parent) {
|
||||
let children = parent._$disconnectableChildren;
|
||||
if (children === undefined) {
|
||||
parent._$disconnectableChildren = children = new Set();
|
||||
}
|
||||
else if (children.has(obj)) {
|
||||
// Once we've reached a parent that already contains this child, we
|
||||
// can short-circuit
|
||||
break;
|
||||
}
|
||||
children.add(obj);
|
||||
installDisconnectAPI(parent);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Changes the parent reference of the ChildPart, and updates the sparse tree of
|
||||
* Disconnectable children accordingly.
|
||||
*
|
||||
* Note, this method will be patched onto ChildPart instances and called from
|
||||
* the core code when parts are moved between different parents.
|
||||
*/
|
||||
function reparentDisconnectables(newParent) {
|
||||
if (this._$disconnectableChildren !== undefined) {
|
||||
removeDisconnectableFromParent(this);
|
||||
this._$parent = newParent;
|
||||
addDisconnectableToParent(this);
|
||||
}
|
||||
else {
|
||||
this._$parent = newParent;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the connected state on any directives contained within the committed
|
||||
* value of this part (i.e. within a TemplateInstance or iterable of
|
||||
* ChildParts) and runs their `disconnected`/`reconnected`s, as well as within
|
||||
* any directives stored on the ChildPart (when `valueOnly` is false).
|
||||
*
|
||||
* `isClearingValue` should be passed as `true` on a top-level part that is
|
||||
* clearing itself, and not as a result of recursively disconnecting directives
|
||||
* as part of a `clear` operation higher up the tree. This both ensures that any
|
||||
* directive on this ChildPart that produced a value that caused the clear
|
||||
* operation is not disconnected, and also serves as a performance optimization
|
||||
* to avoid needless bookkeeping when a subtree is going away; when clearing a
|
||||
* subtree, only the top-most part need to remove itself from the parent.
|
||||
*
|
||||
* `fromPartIndex` is passed only in the case of a partial `_clear` running as a
|
||||
* result of truncating an iterable.
|
||||
*
|
||||
* Note, this method will be patched onto ChildPart instances and called from the
|
||||
* core code when parts are cleared or the connection state is changed by the
|
||||
* user.
|
||||
*/
|
||||
function notifyChildPartConnectedChanged(isConnected, isClearingValue = false, fromPartIndex = 0) {
|
||||
const value = this._$committedValue;
|
||||
const children = this._$disconnectableChildren;
|
||||
if (children === undefined || children.size === 0) {
|
||||
return;
|
||||
}
|
||||
if (isClearingValue) {
|
||||
if (Array.isArray(value)) {
|
||||
// Iterable case: Any ChildParts created by the iterable should be
|
||||
// disconnected and removed from this ChildPart's disconnectable
|
||||
// children (starting at `fromPartIndex` in the case of truncation)
|
||||
for (let i = fromPartIndex; i < value.length; i++) {
|
||||
notifyChildrenConnectedChanged(value[i], false);
|
||||
removeDisconnectableFromParent(value[i]);
|
||||
}
|
||||
}
|
||||
else if (value != null) {
|
||||
// TemplateInstance case: If the value has disconnectable children (will
|
||||
// only be in the case that it is a TemplateInstance), we disconnect it
|
||||
// and remove it from this ChildPart's disconnectable children
|
||||
notifyChildrenConnectedChanged(value, false);
|
||||
removeDisconnectableFromParent(value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyChildrenConnectedChanged(this, isConnected);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Patches disconnection API onto ChildParts.
|
||||
*/
|
||||
const installDisconnectAPI = (obj) => {
|
||||
var _a, _b;
|
||||
var _c, _d;
|
||||
if (obj.type == PartType.CHILD) {
|
||||
(_a = (_c = obj)._$notifyConnectionChanged) !== null && _a !== void 0 ? _a : (_c._$notifyConnectionChanged = notifyChildPartConnectedChanged);
|
||||
(_b = (_d = obj)._$reparentDisconnectables) !== null && _b !== void 0 ? _b : (_d._$reparentDisconnectables = reparentDisconnectables);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* An abstract `Directive` base class whose `disconnected` method will be
|
||||
* called when the part containing the directive is cleared as a result of
|
||||
* re-rendering, or when the user calls `part.setConnected(false)` on
|
||||
* a part that was previously rendered containing the directive (as happens
|
||||
* when e.g. a LitElement disconnects from the DOM).
|
||||
*
|
||||
* If `part.setConnected(true)` is subsequently called on a
|
||||
* containing part, the directive's `reconnected` method will be called prior
|
||||
* to its next `update`/`render` callbacks. When implementing `disconnected`,
|
||||
* `reconnected` should also be implemented to be compatible with reconnection.
|
||||
*
|
||||
* Note that updates may occur while the directive is disconnected. As such,
|
||||
* directives should generally check the `this.isConnected` flag during
|
||||
* render/update to determine whether it is safe to subscribe to resources
|
||||
* that may prevent garbage collection.
|
||||
*/
|
||||
class AsyncDirective extends Directive {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
// @internal
|
||||
this._$disconnectableChildren = undefined;
|
||||
}
|
||||
/**
|
||||
* Initialize the part with internal fields
|
||||
* @param part
|
||||
* @param parent
|
||||
* @param attributeIndex
|
||||
*/
|
||||
_$initialize(part, parent, attributeIndex) {
|
||||
super._$initialize(part, parent, attributeIndex);
|
||||
addDisconnectableToParent(this);
|
||||
this.isConnected = part._$isConnected;
|
||||
}
|
||||
// This property needs to remain unminified.
|
||||
/**
|
||||
* Called from the core code when a directive is going away from a part (in
|
||||
* which case `shouldRemoveFromParent` should be true), and from the
|
||||
* `setChildrenConnected` helper function when recursively changing the
|
||||
* connection state of a tree (in which case `shouldRemoveFromParent` should
|
||||
* be false).
|
||||
*
|
||||
* @param isConnected
|
||||
* @param isClearingDirective - True when the directive itself is being
|
||||
* removed; false when the tree is being disconnected
|
||||
* @internal
|
||||
*/
|
||||
['_$notifyDirectiveConnectionChanged'](isConnected, isClearingDirective = true) {
|
||||
var _a, _b;
|
||||
if (isConnected !== this.isConnected) {
|
||||
this.isConnected = isConnected;
|
||||
if (isConnected) {
|
||||
(_a = this.reconnected) === null || _a === void 0 ? void 0 : _a.call(this);
|
||||
}
|
||||
else {
|
||||
(_b = this.disconnected) === null || _b === void 0 ? void 0 : _b.call(this);
|
||||
}
|
||||
}
|
||||
if (isClearingDirective) {
|
||||
notifyChildrenConnectedChanged(this, isConnected);
|
||||
removeDisconnectableFromParent(this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the value of the directive's Part outside the normal `update`/`render`
|
||||
* lifecycle of a directive.
|
||||
*
|
||||
* This method should not be called synchronously from a directive's `update`
|
||||
* or `render`.
|
||||
*
|
||||
* @param directive The directive to update
|
||||
* @param value The value to set
|
||||
*/
|
||||
setValue(value) {
|
||||
if (isSingleExpression(this.__part)) {
|
||||
this.__part._$setValue(value, this);
|
||||
}
|
||||
else {
|
||||
// this.__attributeIndex will be defined in this case, but
|
||||
// assert it in dev mode
|
||||
if (this.__attributeIndex === undefined) {
|
||||
throw new Error(`Expected this.__attributeIndex to be a number`);
|
||||
}
|
||||
const newValues = [...this.__part._$committedValue];
|
||||
newValues[this.__attributeIndex] = value;
|
||||
this.__part._$setValue(newValues, this, 0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* User callbacks for implementing logic to release any resources/subscriptions
|
||||
* that may have been retained by this directive. Since directives may also be
|
||||
* re-connected, `reconnected` should also be implemented to restore the
|
||||
* working state of the directive prior to the next render.
|
||||
*/
|
||||
disconnected() { }
|
||||
reconnected() { }
|
||||
}
|
||||
|
||||
export { AsyncDirective };
|
||||
//# sourceMappingURL=async-directive.js.map
|
Reference in New Issue
Block a user