Quelle lit.all.mjs
Sprache: unbekannt
|
|
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
const NODE_MODE$1 = false;
const global$2 = window;
/**
* Whether the current browser supports `adoptedStyleSheets`.
*/
const supportsAdoptingStyleSheets = global$2.ShadowRoot &&
(global$2.ShadyCSS === undefined || global$2.ShadyCSS.nativeShadow) &&
'adoptedStyleSheets' in Document.prototype &&
'replace' in CSSStyleSheet.prototype;
const constructionToken = Symbol();
const cssTagCache = new WeakMap();
/**
* A container for a string of CSS text, that may be used to create a CSSStyleSheet.
*
* CSSResult is the return value of `css`-tagged template literals and
* `unsafeCSS()`. In order to ensure that CSSResults are only created via the
* `css` tag and `unsafeCSS()`, CSSResult cannot be constructed directly.
*/
class CSSResult {
constructor(cssText, strings, safeToken) {
// This property needs to remain unminified.
this['_$cssResult$'] = true;
if (safeToken !== constructionToken) {
throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.');
}
this.cssText = cssText;
this._strings = strings;
}
// This is a getter so that it's lazy. In practice, this means stylesheets
// are not created until the first element instance is made.
get styleSheet() {
// If `supportsAdoptingStyleSheets` is true then we assume CSSStyleSheet is
// constructable.
let styleSheet = this._styleSheet;
const strings = this._strings;
if (supportsAdoptingStyleSheets && styleSheet === undefined) {
const cacheable = strings !== undefined && strings.length === 1;
if (cacheable) {
styleSheet = cssTagCache.get(strings);
}
if (styleSheet === undefined) {
(this._styleSheet = styleSheet = new CSSStyleSheet()).replaceSync(this.cssText);
if (cacheable) {
cssTagCache.set(strings, styleSheet);
}
}
}
return styleSheet;
}
toString() {
return this.cssText;
}
}
const textFromCSSResult = (value) => {
// This property needs to remain unminified.
if (value['_$cssResult$'] === true) {
return value.cssText;
}
else if (typeof value === 'number') {
return value;
}
else {
throw new Error(`Value passed to 'css' function must be a 'css' function result: ` +
`${value}. Use 'unsafeCSS' to pass non-literal values, but take care ` +
`to ensure page security.`);
}
};
/**
* Wrap a value for interpolation in a {@linkcode css} tagged template literal.
*
* This is unsafe because untrusted CSS text can be used to phone home
* or exfiltrate data to an attacker controlled site. Take care to only use
* this with trusted input.
*/
const unsafeCSS = (value) => new CSSResult(typeof value === 'string' ? value : String(value), u ndefined, constructionToken);
/**
* A template literal tag which can be used with LitElement's
* {@linkcode LitElement.styles} property to set element styles.
*
* For security reasons, only literal string values and number may be used in
* embedded expressions. To incorporate non-literal values {@linkcode unsafeCSS}
* may be used inside an expression.
*/
const css = (strings, ...values) => {
const cssText = strings.length === 1
? strings[0]
: values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]);
return new CSSResult(cssText, strings, constructionToken);
};
/**
* Applies the given styles to a `shadowRoot`. When Shadow DOM is
* available but `adoptedStyleSheets` is not, styles are appended to the
* `shadowRoot` to [mimic spec behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets).
* Note, when shimming is used, any styles that are subsequently placed into
* the shadowRoot should be placed *before* any shimmed adopted styles. This
* will match spec behavior that gives adopted sheets precedence over styles in
* shadowRoot.
*/
const adoptStyles = (renderRoot, styles) => {
if (supportsAdoptingStyleSheets) {
renderRoot.adoptedStyleSheets = styles.map((s) => s instanceof CSSStyleSheet ? s : s.styleSheet);
}
else {
styles.forEach((s) => {
const style = document.createElement('style');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nonce = global$2['litNonce'];
if (nonce !== undefined) {
style.setAttribute('nonce', nonce);
}
style.textContent = s.cssText;
renderRoot.appendChild(style);
});
}
};
const cssResultFromStyleSheet = (sheet) => {
let cssText = '';
for (const rule of sheet.cssRules) {
cssText += rule.cssText;
}
return unsafeCSS(cssText);
};
const getCompatibleStyle = supportsAdoptingStyleSheets ||
(NODE_MODE$1 )
? (s) => s
: (s) => s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s;
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
var _d$1;
var _e;
const global$1 = window;
const trustedTypes$1 = global$1
.trustedTypes;
// Temporary workaround for https://crbug.com/993268
// Currently, any attribute starting with "on" is considered to be a
// TrustedScript source. Such boolean attributes must be set to the equivalent
// trusted emptyScript value.
const emptyStringForBooleanAttribute$1 = trustedTypes$1
? trustedTypes$1.emptyScript
: '';
const polyfillSupport$2 = global$1.reactiveElementPolyfillSupport;
/*
* When using Closure Compiler, JSCompiler_renameProperty(property, object) is
* replaced at compile time by the munged name for object[property]. We cannot
* alias this function, so we have to use a small shim that has the same
* behavior when not compiling.
*/
/*@__INLINE__*/
const JSCompiler_renameProperty = (prop, _obj) => prop;
const defaultConverter = {
toAttribute(value, type) {
switch (type) {
case Boolean:
value = value ? emptyStringForBooleanAttribute$1 : null;
break;
case Object:
case Array:
// if the value is `null` or `undefined` pass this through
// to allow removing/no change behavior.
value = value == null ? value : JSON.stringify(value);
break;
}
return value;
},
fromAttribute(value, type) {
let fromValue = value;
switch (type) {
case Boolean:
fromValue = value !== null;
break;
case Number:
fromValue = value === null ? null : Number(value);
break;
case Object:
case Array:
// Do *not* generate exception when invalid JSON is set as elements
// don't normally complain on being mis-configured.
// TODO(sorvell): Do generate exception in *dev mode*.
try {
// Assert to adhere to Bazel's "must type assert JSON parse" rule.
fromValue = JSON.parse(value);
}
catch (e) {
fromValue = null;
}
break;
}
return fromValue;
},
};
/**
* Change function that returns true if `value` is different from `oldValue`.
* This method is used as the default for a property's `hasChanged` function.
*/
const notEqual = (value, old) => {
// This ensures (old==NaN, value==NaN) always returns false
return old !== value && (old === old || value === value);
};
const defaultPropertyDeclaration = {
attribute: true,
type: String,
converter: defaultConverter,
reflect: false,
hasChanged: notEqual,
};
/**
* The Closure JS Compiler doesn't currently have good support for static
* property semantics where "this" is dynamic (e.g.
* https://github.com/google/closure-compiler/issues/3177 and others) so we use
* this hack to bypass any rewriting by the compiler.
*/
const finalized = 'finalized';
/**
* Base element class which manages element properties and attributes. When
* properties change, the `update` method is asynchronously called. This method
* should be supplied by subclassers to render updates as desired.
* @noInheritDoc
*/
class ReactiveElement extends HTMLElement {
constructor() {
super();
this.__instanceProperties = new Map();
/**
* True if there is a pending update as a result of calling `requestUpdate()`.
* Should only be read.
* @category updates
*/
this.isUpdatePending = false;
/**
* Is set to `true` after the first update. The element code cannot assume
* that `renderRoot` exists before the element `hasUpdated`.
* @category updates
*/
this.hasUpdated = false;
/**
* Name of currently reflecting property
*/
this.__reflectingProperty = null;
this._initialize();
}
/**
* Adds an initializer function to the class that is called during instance
* construction.
*
* This is useful for code that runs against a `ReactiveElement`
* subclass, such as a decorator, that needs to do work for each
* instance, such as setting up a `ReactiveController`.
*
* ```ts
* const myDecorator = (target: typeof ReactiveElement, key: string) => {
* target.addInitializer((instance: ReactiveElement) => {
* // This is run during construction of the element
* new MyController(instance);
* });
* }
* ```
*
* Decorating a field will then cause each instance to run an initializer
* that adds a controller:
*
* ```ts
* class MyElement extends LitElement {
* @myDecorator foo;
* }
* ```
*
* Initializers are stored per-constructor. Adding an initializer to a
* subclass does not add it to a superclass. Since initializers are run in
* constructors, initializers will run in order of the class hierarchy,
* starting with superclasses and progressing to the instance's class.
*
* @nocollapse
*/
static addInitializer(initializer) {
var _a;
this.finalize();
((_a = this._initializers) !== null && _a !== void 0 ? _a : (this._initializers = [])).push(initializer);
}
/**
* Returns a list of attributes corresponding to the registered properties.
* @nocollapse
* @category attributes
*/
static get observedAttributes() {
// note: piggy backing on this to ensure we're finalized.
this.finalize();
const attributes = [];
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
this.elementProperties.forEach((v, p) => {
const attr = this.__attributeNameForProperty(p, v);
if (attr !== undefined) {
this.__attributeToPropertyMap.set(attr, p);
attributes.push(attr);
}
});
return attributes;
}
/**
* Creates a property accessor on the element prototype if one does not exist
* and stores a {@linkcode PropertyDeclaration} for the property with the
* given options. The property setter calls the property's `hasChanged`
* property option or uses a strict identity check to determine whether or not
* to request an update.
*
* This method may be overridden to customize properties; however,
* when doing so, it's important to call `super.createProperty` to ensure
* the property is setup correctly. This method calls
* `getPropertyDescriptor` internally to get a descriptor to install.
* To customize what properties do when they are get or set, override
* `getPropertyDescriptor`. To customize the options for a property,
* implement `createProperty` like this:
*
* ```ts
* static createProperty(name, options) {
* options = Object.assign(options, {myOption: true});
* super.createProperty(name, options);
* }
* ```
*
* @nocollapse
* @category properties
*/
static createProperty(name, options = defaultPropertyDeclaration) {
// if this is a state property, force the attribute to false.
if (options.state) {
// Cast as any since this is readonly.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options.attribute = false;
}
// Note, since this can be called by the `@property` decorator which
// is called before `finalize`, we ensure finalization has been kicked off.
this.finalize();
this.elementProperties.set(name, options);
// Do not generate an accessor if the prototype already has one, since
// it would be lost otherwise and that would never be the user's intention;
// Instead, we expect users to call `requestUpdate` themselves from
// user-defined accessors. Note that if the super has an accessor we will
// still overwrite it
if (!options.noAccessor && !this.prototype.hasOwnProperty(name)) {
const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
const descriptor = this.getPropertyDescriptor(name, key, options);
if (descriptor !== undefined) {
Object.defineProperty(this.prototype, name, descriptor);
}
}
}
/**
* Returns a property descriptor to be defined on the given named property.
* If no descriptor is returned, the property will not become an accessor.
* For example,
*
* ```ts
* class MyElement extends LitElement {
* static getPropertyDescriptor(name, key, options) {
* const defaultDescriptor =
* super.getPropertyDescriptor(name, key, options);
* const setter = defaultDescriptor.set;
* return {
* get: defaultDescriptor.get,
* set(value) {
* setter.call(this, value);
* // custom action.
* },
* configurable: true,
* enumerable: true
* }
* }
* }
* ```
*
* @nocollapse
* @category properties
*/
static getPropertyDescriptor(name, key, options) {
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get() {
return this[key];
},
set(value) {
const oldValue = this[name];
this[key] = value;
this.requestUpdate(name, oldValue, options);
},
configurable: true,
enumerable: true,
};
}
/**
* Returns the property options associated with the given property.
* These options are defined with a `PropertyDeclaration` via the `properties`
* object or the `@property` decorator and are registered in
* `createProperty(...)`.
*
* Note, this method should be considered "final" and not overridden. To
* customize the options for a given property, override
* {@linkcode createProperty}.
*
* @nocollapse
* @final
* @category properties
*/
static getPropertyOptions(name) {
return this.elementProperties.get(name) || defaultPropertyDeclaration;
}
/**
* Creates property accessors for registered properties, sets up element
* styling, and ensures any superclasses are also finalized. Returns true if
* the element was finalized.
* @nocollapse
*/
static finalize() {
if (this.hasOwnProperty(finalized)) {
return false;
}
this[finalized] = true;
// finalize any superclasses
const superCtor = Object.getPrototypeOf(this);
superCtor.finalize();
// Create own set of initializers for this class if any exist on the
// superclass and copy them down. Note, for a small perf boost, avoid
// creating initializers unless needed.
if (superCtor._initializers !== undefined) {
this._initializers = [...superCtor._initializers];
}
this.elementProperties = new Map(superCtor.elementProperties);
// initialize Map populated in observedAttributes
this.__attributeToPropertyMap = new Map();
// make any properties
// Note, only process "own" properties since this element will inherit
// any properties defined on the superClass, and finalization ensures
// the entire prototype chain is finalized.
if (this.hasOwnProperty(JSCompiler_renameProperty('properties'))) {
const props = this.properties;
// support symbols in properties (IE11 does not support this)
const propKeys = [
...Object.getOwnPropertyNames(props),
...Object.getOwnPropertySymbols(props),
];
// This for/of is ok because propKeys is an array
for (const p of propKeys) {
// note, use of `any` is due to TypeScript lack of support for symbol in
// index types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.createProperty(p, props[p]);
}
}
this.elementStyles = this.finalizeStyles(this.styles);
return true;
}
/**
* Takes the styles the user supplied via the `static styles` property and
* returns the array of styles to apply to the element.
* Override this method to integrate into a style management system.
*
* Styles are deduplicated preserving the _last_ instance in the list. This
* is a performance optimization to avoid duplicated styles that can occur
* especially when composing via subclassing. The last item is kept to try
* to preserve the cascade order with the assumption that it's most important
* that last added styles override previous styles.
*
* @nocollapse
* @category styles
*/
static finalizeStyles(styles) {
const elementStyles = [];
if (Array.isArray(styles)) {
// Dedupe the flattened array in reverse order to preserve the last items.
// Casting to Array<unknown> works around TS error that
// appears to come from trying to flatten a type CSSResultArray.
const set = new Set(styles.flat(Infinity).reverse());
// Then preserve original order by adding the set items in reverse order.
for (const s of set) {
elementStyles.unshift(getCompatibleStyle(s));
}
}
else if (styles !== undefined) {
elementStyles.push(getCompatibleStyle(styles));
}
return elementStyles;
}
/**
* Returns the property name for the given attribute `name`.
* @nocollapse
*/
static __attributeNameForProperty(name, options) {
const attribute = options.attribute;
return attribute === false
? undefined
: typeof attribute === 'string'
? attribute
: typeof name === 'string'
? name.toLowerCase()
: undefined;
}
/**
* Internal only override point for customizing work done when elements
* are constructed.
*
* @internal
*/
_initialize() {
var _a;
this.__updatePromise = new Promise((res) => (this.enableUpdating = res));
this._$changedProperties = new Map();
this.__saveInstanceProperties();
// ensures first update will be caught by an early access of
// `updateComplete`
this.requestUpdate();
(_a = this.constructor._initializers) === null || _a === void 0 ? void 0 : _a.forEach((i) => i(this));
}
/**
* Registers a `ReactiveController` to participate in the element's reactive
* update cycle. The element automatically calls into any registered
* controllers during its lifecycle callbacks.
*
* If the element is connected when `addController()` is called, the
* controller's `hostConnected()` callback will be immediately called.
* @category controllers
*/
addController(controller) {
var _a, _b;
((_a = this.__controllers) !== null && _a !== void 0 ? _a : (this.__controllers = [])).push(controller);
// If a controller is added after the element has been connected,
// call hostConnected. Note, re-using existence of `renderRoot` here
// (which is set in connectedCallback) to avoid the need to track a
// first connected state.
if (this.renderRoot !== undefined && this.isConnected) {
(_b = controller.hostConnected) === null || _b === void 0 ? void 0 : _b.call(controller);
}
}
/**
* Removes a `ReactiveController` from the element.
* @category controllers
*/
removeController(controller) {
var _a;
// Note, if the indexOf is -1, the >>> will flip the sign which makes the
// splice do nothing.
(_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.splice(this.__controllers.indexOf(controller) >>> 0, 1);
}
/**
* Fixes any properties set on the instance before upgrade time.
* Otherwise these would shadow the accessor and break these properties.
* The properties are stored in a Map which is played back after the
* constructor runs. Note, on very old versions of Safari (<=9) or Chrome
* (<=41), properties created for native platform properties like (`id` or
* `name`) may not have default values set in the element constructor. On
* these browsers native properties appear on instances and therefore their
* default value will overwrite any element default (e.g. if the element sets
* this.id = 'id' in the constructor, the 'id' will become '' since this is
* the native platform default).
*/
__saveInstanceProperties() {
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
this.constructor.elementProperties.forEach((_v, p) => {
if (this.hasOwnProperty(p)) {
this.__instanceProperties.set(p, this[p]);
delete this[p];
}
});
}
/**
* Returns the node into which the element should render and by default
* creates and returns an open shadowRoot. Implement to customize where the
* element's DOM is rendered. For example, to render into the element's
* childNodes, return `this`.
*
* @return Returns a node into which to render.
* @category rendering
*/
createRenderRoot() {
var _a;
const renderRoot = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this.attachShadow(this.constructor.shadowRootOptions);
adoptStyles(renderRoot, this.constructor.elementStyles);
return renderRoot;
}
/**
* On first connection, creates the element's renderRoot, sets up
* element styling, and enables updating.
* @category lifecycle
*/
connectedCallback() {
var _a;
// create renderRoot before first update.
if (this.renderRoot === undefined) {
this.renderRoot = this.createRenderRoot();
}
this.enableUpdating(true);
(_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostConnected) === null || _a === void 0 ? void 0 : _a.call(c); });
}
/**
* Note, this method should be considered final and not overridden. It is
* overridden on the element instance with a function that triggers the first
* update.
* @category updates
*/
enableUpdating(_requestedUpdate) { }
/**
* Allows for `super.disconnectedCallback()` in extensions while
* reserving the possibility of making non-breaking feature additions
* when disconnecting at some point in the future.
* @category lifecycle
*/
disconnectedCallback() {
var _a;
(_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostDisconnected) === null || _a === void 0 ? void 0 : _a.call(c); });
}
/**
* Synchronizes property values when attributes change.
*
* Specifically, when an attribute is set, the corresponding property is set.
* You should rarely need to implement this callback. If this method is
* overridden, `super.attributeChangedCallback(name, _old, value)` must be
* called.
*
* See [using the lifecycle callbacks](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks)
* on MDN for more information about the `attributeChangedCallback`.
* @category attributes
*/
attributeChangedCallback(name, _old, value) {
this._$attributeToProperty(name, value);
}
__propertyToAttribute(name, value, options = defaultPropertyDeclaration) {
var _a;
const attr = this.constructor.__attributeNameForProperty(name, options);
if (attr !== undefined && options.reflect === true) {
const converter = ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.toAttribute) !==
undefined
? options.converter
: defaultConverter;
const attrValue = converter.toAttribute(value, options.type);
// Track if the property is being reflected to avoid
// setting the property again via `attributeChangedCallback`. Note:
// 1. this takes advantage of the fact that the callback is synchronous.
// 2. will behave incorrectly if multiple attributes are in the reaction
// stack at time of calling. However, since we process attributes
// in `update` this should not be possible (or an extreme corner case
// that we'd like to discover).
// mark state reflecting
this.__reflectingProperty = name;
if (attrValue == null) {
this.removeAttribute(attr);
}
else {
this.setAttribute(attr, attrValue);
}
// mark state not reflecting
this.__reflectingProperty = null;
}
}
/** @internal */
_$attributeToProperty(name, value) {
var _a;
const ctor = this.constructor;
// Note, hint this as an `AttributeMap` so closure clearly understands
// the type; it has issues with tracking types through statics
const propName = ctor.__attributeToPropertyMap.get(name);
// Use tracking info to avoid reflecting a property value to an attribute
// if it was just set because the attribute changed.
if (propName !== undefined && this.__reflectingProperty !== propName) {
const options = ctor.getPropertyOptions(propName);
const converter = typeof options.converter === 'function'
? { fromAttribute: options.converter }
: ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.fromAttribute) !== undefined
? options.converter
: defaultConverter;
// mark state reflecting
this.__reflectingProperty = propName;
this[propName] = converter.fromAttribute(value, options.type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
);
// mark state not reflecting
this.__reflectingProperty = null;
}
}
/**
* Requests an update which is processed asynchronously. This should be called
* when an element should update based on some state not triggered by setting
* a reactive property. In this case, pass no arguments. It should also be
* called when manually implementing a property setter. In this case, pass the
* property `name` and `oldValue` to ensure that any configured property
* options are honored.
*
* @param name name of requesting property
* @param oldValue old value of requesting property
* @param options property options to use instead of the previously
* configured options
* @category updates
*/
requestUpdate(name, oldValue, options) {
let shouldRequestUpdate = true;
// If we have a property key, perform property update steps.
if (name !== undefined) {
options =
options ||
this.constructor.getPropertyOptions(name);
const hasChanged = options.hasChanged || notEqual;
if (hasChanged(this[name], oldValue)) {
if (!this._$changedProperties.has(name)) {
this._$changedProperties.set(name, oldValue);
}
// Add to reflecting properties set.
// Note, it's important that every change has a chance to add the
// property to `_reflectingProperties`. This ensures setting
// attribute + property reflects correctly.
if (options.reflect === true && this.__reflectingProperty !== name) {
if (this.__reflectingProperties === undefined) {
this.__reflectingProperties = new Map();
}
this.__reflectingProperties.set(name, options);
}
}
else {
// Abort the request if the property should not be considered changed.
shouldRequestUpdate = false;
}
}
if (!this.isUpdatePending && shouldRequestUpdate) {
this.__updatePromise = this.__enqueueUpdate();
}
// Note, since this no longer returns a promise, in dev mode we return a
// thenable which warns if it's called.
return undefined;
}
/**
* Sets up the element to asynchronously update.
*/
async __enqueueUpdate() {
this.isUpdatePending = true;
try {
// Ensure any previous update has resolved before updating.
// This `await` also ensures that property changes are batched.
await this.__updatePromise;
}
catch (e) {
// Refire any previous errors async so they do not disrupt the update
// cycle. Errors are refired so developers have a chance to observe
// them, and this can be done by implementing
// `window.onunhandledrejection`.
Promise.reject(e);
}
const result = this.scheduleUpdate();
// If `scheduleUpdate` returns a Promise, we await it. This is done to
// enable coordinating updates with a scheduler. Note, the result is
// checked to avoid delaying an additional microtask unless we need to.
if (result != null) {
await result;
}
return !this.isUpdatePending;
}
/**
* Schedules an element update. You can override this method to change the
* timing of updates by returning a Promise. The update will await the
* returned Promise, and you should resolve the Promise to allow the update
* to proceed. If this method is overridden, `super.scheduleUpdate()`
* must be called.
*
* For instance, to schedule updates to occur just before the next frame:
*
* ```ts
* override protected async scheduleUpdate(): Promise<unknown> {
* await new Promise((resolve) => requestAnimationFrame(() => resolve()));
* super.scheduleUpdate();
* }
* ```
* @category updates
*/
scheduleUpdate() {
return this.performUpdate();
}
/**
* Performs an element update. Note, if an exception is thrown during the
* update, `firstUpdated` and `updated` will not be called.
*
* Call `performUpdate()` to immediately process a pending update. This should
* generally not be needed, but it can be done in rare cases when you need to
* update synchronously.
*
* Note: To ensure `performUpdate()` synchronously completes a pending update,
* it should not be overridden. In LitElement 2.x it was suggested to override
* `performUpdate()` to also customizing update scheduling. Instead, you should now
* override `scheduleUpdate()`. For backwards compatibility with LitElement 2.x,
* scheduling updates via `performUpdate()` continues to work, but will make
* also calling `performUpdate()` to synchronously process updates difficult.
*
* @category updates
*/
performUpdate() {
var _b;
// Abort any update if one is not pending when this is called.
// This can happen if `performUpdate` is called early to "flush"
// the update.
if (!this.isUpdatePending) {
return;
}
// create renderRoot before first update.
if (!this.hasUpdated) ;
// Mixin instance properties once, if they exist.
if (this.__instanceProperties) {
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.__instanceProperties.forEach((v, p) => (this[p] = v));
this.__instanceProperties = undefined;
}
let shouldUpdate = false;
const changedProperties = this._$changedProperties;
try {
shouldUpdate = this.shouldUpdate(changedProperties);
if (shouldUpdate) {
this.willUpdate(changedProperties);
(_b = this.__controllers) === null || _b === void 0 ? void 0 : _b.forEach((c) => { var _a; return (_a = c.hostUpdate) === null || _a === void 0 ? void 0 : _a.call(c); });
this.update(changedProperties);
}
else {
this.__markUpdated();
}
}
catch (e) {
// Prevent `firstUpdated` and `updated` from running when there's an
// update exception.
shouldUpdate = false;
// Ensure element can accept additional updates after an exception.
this.__markUpdated();
throw e;
}
// The update is no longer considered pending and further updates are now allowed.
if (shouldUpdate) {
this._$didUpdate(changedProperties);
}
}
/**
* Invoked before `update()` to compute values needed during the update.
*
* Implement `willUpdate` to compute property values that depend on other
* properties and are used in the rest of the update process.
*
* ```ts
* willUpdate(changedProperties) {
* // only need to check changed properties for an expensive computation.
* if (changedProperties.has('firstName') || changedProperties.has('lastName')) {
* this.sha = computeSHA(`${this.firstName} ${this.lastName}`);
* }
* }
*
* render() {
* return html`SHA: ${this.sha}`;
* }
* ```
*
* @category updates
*/
willUpdate(_changedProperties) { }
// Note, this is an override point for polyfill-support.
// @internal
_$didUpdate(changedProperties) {
var _a;
(_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostUpdated) === null || _a === void 0 ? void 0 : _a.call(c); });
if (!this.hasUpdated) {
this.hasUpdated = true;
this.firstUpdated(changedProperties);
}
this.updated(changedProperties);
}
__markUpdated() {
this._$changedProperties = new Map();
this.isUpdatePending = false;
}
/**
* Returns a Promise that resolves when the element has completed updating.
* The Promise value is a boolean that is `true` if the element completed the
* update without triggering another update. The Promise result is `false` if
* a property was set inside `updated()`. If the Promise is rejected, an
* exception was thrown during the update.
*
* To await additional asynchronous work, override the `getUpdateComplete`
* method. For example, it is sometimes useful to await a rendered element
* before fulfilling this Promise. To do this, first await
* `super.getUpdateComplete()`, then any subsequent state.
*
* @return A promise of a boolean that resolves to true if the update completed
* without triggering another update.
* @category updates
*/
get updateComplete() {
return this.getUpdateComplete();
}
/**
* Override point for the `updateComplete` promise.
*
* It is not safe to override the `updateComplete` getter directly due to a
* limitation in TypeScript which means it is not possible to call a
* superclass getter (e.g. `super.updateComplete.then(...)`) when the target
* language is ES5 (https://github.com/microsoft/TypeScript/issues/338).
* This method should be overridden instead. For example:
*
* ```ts
* class MyElement extends LitElement {
* override async getUpdateComplete() {
* const result = await super.getUpdateComplete();
* await this._myChild.updateComplete;
* return result;
* }
* }
* ```
*
* @return A promise of a boolean that resolves to true if the update completed
* without triggering another update.
* @category updates
*/
getUpdateComplete() {
return this.__updatePromise;
}
/**
* Controls whether or not `update()` should be called when the element requests
* an update. By default, this method always returns `true`, but this can be
* customized to control when to update.
*
* @param _changedProperties Map of changed properties with old values
* @category updates
*/
shouldUpdate(_changedProperties) {
return true;
}
/**
* Updates the element. This method reflects property values to attributes.
* It can be overridden to render and keep updated element DOM.
* Setting properties inside this method will *not* trigger
* another update.
*
* @param _changedProperties Map of changed properties with old values
* @category updates
*/
update(_changedProperties) {
if (this.__reflectingProperties !== undefined) {
// Use forEach so this works even if for/of loops are compiled to for
// loops expecting arrays
this.__reflectingProperties.forEach((v, k) => this.__propertyToAttribute(k, this[k], v));
this.__reflectingProperties = undefined;
}
this.__markUpdated();
}
/**
* Invoked whenever the element is updated. Implement to perform
* post-updating tasks via DOM APIs, for example, focusing an element.
*
* Setting properties inside this method will trigger the element to update
* again after this update cycle completes.
*
* @param _changedProperties Map of changed properties with old values
* @category updates
*/
updated(_changedProperties) { }
/**
* Invoked when the element is first updated. Implement to perform one time
* work on the element after update.
*
* ```ts
* firstUpdated() {
* this.renderRoot.getElementById('my-text-area').focus();
* }
* ```
*
* Setting properties inside this method will trigger the element to update
* again after this update cycle completes.
*
* @param _changedProperties Map of changed properties with old values
* @category updates
*/
firstUpdated(_changedProperties) { }
}
_e = finalized;
/**
* Marks class as having finished creating properties.
*/
ReactiveElement[_e] = true;
/**
* Memoized list of all element properties, including any superclass properties.
* Created lazily on user subclasses when finalizing the class.
* @nocollapse
* @category properties
*/
ReactiveElement.elementProperties = new Map();
/**
* Memoized list of all element styles.
* Created lazily on user subclasses when finalizing the class.
* @nocollapse
* @category styles
*/
ReactiveElement.elementStyles = [];
/**
* Options used when calling `attachShadow`. Set this property to customize
* the options for the shadowRoot; for example, to create a closed
* shadowRoot: `{mode: 'closed'}`.
*
* Note, these options are used in `createRenderRoot`. If this method
* is customized, options should be respected if possible.
* @nocollapse
* @category rendering
*/
ReactiveElement.shadowRootOptions = { mode: 'open' };
// Apply polyfills if available
polyfillSupport$2 === null || polyfillSupport$2 === void 0 ? void 0 : polyfillSupport$2({ ReactiveElement });
// IMPORTANT: do not change the property name or the assignment expression.
// This line will be used in regexes to search for ReactiveElement usage.
((_d$1 = global$1.reactiveElementVersions) !== null && _d$1 !== void 0 ? _d$1 : (global$1.reactiveElementVersions = [])).push('1.5.0');
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
var _d;
// Use window for browser builds because IE11 doesn't have globalThis.
const global = window;
const __moz_domParser = new DOMParser();
const wrap$1 = (node) => node;
const trustedTypes = global.trustedTypes;
/**
* Our TrustedTypePolicy for HTML which is declared using the html template
* tag function.
*
* That HTML is a developer-authored constant, and is parsed with innerHTML
* before any untrusted expressions have been mixed in. Therefor it is
* considered safe by construction.
*/
const policy = trustedTypes
? trustedTypes.createPolicy('lit-html', {
createHTML: (s) => s,
})
: undefined;
// Added to an attribute name to mark the attribute as bound so we can find
// it easily.
const boundAttributeSuffix = '$lit$';
// This marker is used in many syntactic positions in HTML, so it must be
// a valid element name and attribute name. We don't support dynamic names (yet)
// but this at least ensures that the parse tree is closer to the template
// intention.
const marker = `lit$${String(Math.random()).slice(9)}$`;
// String used to tell if a comment is a marker comment
const markerMatch = '?' + marker;
// Text used to insert a comment marker node. We use processing instruction
// syntax because it's slightly smaller, but parses as a comment node.
const nodeMarker = `<${markerMatch}>`;
const d = document;
// Creates a dynamic marker. We never have to search for these in the DOM.
const createMarker$1 = (v = '') => d.createComment(v);
const isPrimitive$1 = (value) => value === null || (typeof value != 'object' && typeof value != 'function');
const isArray = Array.isArray;
const isIterable = (value) => isArray(value) ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
typeof (value === null || value === void 0 ? void 0 : value[Symbol.iterator]) === 'function';
const SPACE_CHAR = `[ \t\n\f\r]`;
const ATTR_VALUE_CHAR = `[^ \t\n\f\r"'\`<>=]`;
const NAME_CHAR = `[^\\s"'>=/]`;
// These regexes represent the five parsing states that we care about in the
// Template's HTML scanner. They match the *end* of the state they're named
// after.
// Depending on the match, we transition to a new state. If there's no match,
// we stay in the same state.
// Note that the regexes are stateful. We utilize lastIndex and sync it
// across the multiple regexes used. In addition to the five regexes below
// we also dynamically create a regex to find the matching end tags for raw
// text elements.
/**
* End of text is: `<` followed by:
* (comment start) or (tag) or (dynamic tag binding)
*/
const textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g;
const COMMENT_START = 1;
const TAG_NAME = 2;
const DYNAMIC_TAG_NAME = 3;
const commentEndRegex = /-->/g;
/**
* Comments not started with <!--, like </{, can be ended by a single `>`
*/
const comment2EndRegex = />/g;
/**
* The tagEnd regex matches the end of the "inside an opening" tag syntax
* position. It either matches a `>`, an attribute-like sequence, or the end
* of the string after a space (attribute-name position ending).
*
* See attributes in the HTML spec:
* https://www.w3.org/TR/html5/syntax.html#elements-attributes
*
* " \t\n\f\r" are HTML space characters:
* https://infra.spec.whatwg.org/#ascii-whitespace
*
* So an attribute is:
* * The name: any character except a whitespace character, ("), ('), ">",
* "=", or "/". Note: this is different from the HTML spec which also excludes control characters.
* * Followed by zero or more space characters
* * Followed by "="
* * Followed by zero or more space characters
* * Followed by:
* * Any character except space, ('), ("), "<", ">", "=", (`), or
* * (") then any non-("), or
* * (') then any non-(')
*/
const tagEndRegex = new RegExp(`>|${SPACE_CHAR}(?:(${NAME_CHAR}+)(${SPACE_CHAR}*=${SPACE_CHAR}*(?:${ATTR_VALUE_CHAR}|("|')|))|$)`, 'g');
const ENTIRE_MATCH = 0;
const ATTRIBUTE_NAME = 1;
const SPACES_AND_EQUALS = 2;
const QUOTE_CHAR = 3;
const singleQuoteAttrEndRegex = /'/g;
const doubleQuoteAttrEndRegex = /"/g;
/**
* Matches the raw text elements.
*
* Comments are not parsed within raw text elements, so we need to search their
* text content for marker strings.
*/
const rawTextElement = /^(?:script|style|textarea|title)$/i;
/** TemplateResult types */
const HTML_RESULT$1 = 1;
const SVG_RESULT$1 = 2;
// TemplatePart types
// IMPORTANT: these must match the values in PartType
const ATTRIBUTE_PART = 1;
const CHILD_PART = 2;
const PROPERTY_PART = 3;
const BOOLEAN_ATTRIBUTE_PART = 4;
const EVENT_PART = 5;
const ELEMENT_PART = 6;
const COMMENT_PART = 7;
/**
* Generates a template literal tag function that returns a TemplateResult with
* the given result type.
*/
const tag = (type) => (strings, ...values) => {
return {
// This property needs to remain unminified.
['_$litType$']: type,
strings,
values,
};
};
/**
* Interprets a template literal as an HTML template that can efficiently
* render to and update a container.
*
* ```ts
* const header = (title: string) => html`<h1>${title}</h1>`;
* ```
*
* The `html` tag returns a description of the DOM to render as a value. It is
* lazy, meaning no work is done until the template is rendered. When rendering,
* if a template comes from the same expression as a previously rendered result,
* it's efficiently updated instead of replaced.
*/
const html$1 = tag(HTML_RESULT$1);
/**
* Interprets a template literal as an SVG fragment that can efficiently
* render to and update a container.
*
* ```ts
* const rect = svg`<rect width="10" height="10"></rect>`;
*
* const myImage = html`
* <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
* ${rect}
* </svg>`;
* ```
*
* The `svg` *tag function* should only be used for SVG fragments, or elements
* that would be contained **inside** an `<svg>` HTML element. A common error is
* placing an `<svg>` *element* in a template tagged with the `svg` tag
* function. The `<svg>` element is an HTML element and should be used within a
* template tagged with the {@linkcode html} tag function.
*
* In LitElement usage, it's invalid to return an SVG fragment from the
* `render()` method, as the SVG fragment will be contained within the element's
* shadow root and thus cannot be used within an `<svg>` HTML element.
*/
const svg$1 = tag(SVG_RESULT$1);
/**
* A sentinel value that signals that a value was handled by a directive and
* should not be written to the DOM.
*/
const noChange = Symbol.for('lit-noChange');
/**
* A sentinel value that signals a ChildPart to fully clear its content.
*
* ```ts
* const button = html`${
* user.isAdmin
* ? html`<button>DELETE</button>`
* : nothing
* }`;
* ```
*
* Prefer using `nothing` over other falsy values as it provides a consistent
* behavior between various expression binding contexts.
*
* In child expressions, `undefined`, `null`, `''`, and `nothing` all behave the
* same and render no nodes. In attribute expressions, `nothing` _removes_ the
* attribute, while `undefined` and `null` will render an empty string. In
* property expressions `nothing` becomes `undefined`.
*/
const nothing = Symbol.for('lit-nothing');
/**
* The cache of prepared templates, keyed by the tagged TemplateStringsArray
* and _not_ accounting for the specific template tag used. This means that
* template tags cannot be dynamic - the must statically be one of html, svg,
* or attr. This restriction simplifies the cache lookup, which is on the hot
* path for rendering.
*/
const templateCache = new WeakMap();
const walker = d.createTreeWalker(d, 129 /* NodeFilter.SHOW_{ELEMENT|COMMENT} */, null, false);
/**
* Returns an HTML string for the given TemplateStringsArray and result type
* (HTML or SVG), along with the case-sensitive bound attribute names in
* template order. The HTML contains comment markers denoting the `ChildPart`s
* and suffixes on bound attributes denoting the `AttributeParts`.
*
* @param strings template strings array
* @param type HTML or SVG
* @return Array containing `[html, attrNames]` (array returned for terseness,
* to avoid object fields since this code is shared with non-minified SSR
* code)
*/
const getTemplateHtml = (strings, type) => {
// Insert makers into the template HTML to represent the position of
// bindings. The following code scans the template strings to determine the
// syntactic position of the bindings. They can be in text position, where
// we insert an HTML comment, attribute value position, where we insert a
// sentinel string and re-write the attribute name, or inside a tag where
// we insert the sentinel string.
const l = strings.length - 1;
// Stores the case-sensitive bound attribute names in the order of their
// parts. ElementParts are also reflected in this array as undefined
// rather than a string, to disambiguate from attribute bindings.
const attrNames = [];
let html = type === SVG_RESULT$1 ? '<svg>' : '';
// When we're inside a raw text tag (not it's text content), the regex
// will still be tagRegex so we can find attributes, but will switch to
// this regex when the tag ends.
let rawTextEndRegex;
// The current parsing state, represented as a reference to one of the
// regexes
let regex = textEndRegex;
for (let i = 0; i < l; i++) {
const s = strings[i];
// The index of the end of the last attribute name. When this is
// positive at end of a string, it means we're in an attribute value
// position and need to rewrite the attribute name.
// We also use a special value of -2 to indicate that we encountered
// the end of a string in attribute name position.
let attrNameEndIndex = -1;
let attrName;
let lastIndex = 0;
let match;
// The conditions in this loop handle the current parse state, and the
// assignments to the `regex` variable are the state transitions.
while (lastIndex < s.length) {
// Make sure we start searching from where we previously left off
regex.lastIndex = lastIndex;
match = regex.exec(s);
if (match === null) {
break;
}
lastIndex = regex.lastIndex;
if (regex === textEndRegex) {
if (match[COMMENT_START] === '!--') {
regex = commentEndRegex;
}
else if (match[COMMENT_START] !== undefined) {
// We started a weird comment, like </{
regex = comment2EndRegex;
}
else if (match[TAG_NAME] !== undefined) {
if (rawTextElement.test(match[TAG_NAME])) {
// Record if we encounter a raw-text element. We'll switch to
// this regex at the end of the tag.
rawTextEndRegex = new RegExp(`</${match[TAG_NAME]}`, 'g');
}
regex = tagEndRegex;
}
else if (match[DYNAMIC_TAG_NAME] !== undefined) {
regex = tagEndRegex;
}
}
else if (regex === tagEndRegex) {
if (match[ENTIRE_MATCH] === '>') {
// End of a tag. If we had started a raw-text element, use that
// regex
regex = rawTextEndRegex !== null && rawTextEndRegex !== void 0 ? rawTextEndRegex : textEndRegex;
// We may be ending an unquoted attribute value, so make sure we
// clear any pending attrNameEndIndex
attrNameEndIndex = -1;
}
else if (match[ATTRIBUTE_NAME] === undefined) {
// Attribute name position
attrNameEndIndex = -2;
}
else {
attrNameEndIndex = regex.lastIndex - match[SPACES_AND_EQUALS].length;
attrName = match[ATTRIBUTE_NAME];
regex =
match[QUOTE_CHAR] === undefined
? tagEndRegex
: match[QUOTE_CHAR] === '"'
? doubleQuoteAttrEndRegex
: singleQuoteAttrEndRegex;
}
}
else if (regex === doubleQuoteAttrEndRegex ||
regex === singleQuoteAttrEndRegex) {
regex = tagEndRegex;
}
else if (regex === commentEndRegex || regex === comment2EndRegex) {
regex = textEndRegex;
}
else {
// Not one of the five state regexes, so it must be the dynamically
// created raw text regex and we're at the close of that element.
regex = tagEndRegex;
rawTextEndRegex = undefined;
}
}
// We have four cases:
// 1. We're in text position, and not in a raw text element
// (regex === textEndRegex): insert a comment marker.
// 2. We have a non-negative attrNameEndIndex which means we need to
// rewrite the attribute name to add a bound attribute suffix.
// 3. We're at the non-first binding in a multi-binding attribute, use a
// plain marker.
// 4. We're somewhere else inside the tag. If we're in attribute name
// position (attrNameEndIndex === -2), add a sequential suffix to
// generate a unique attribute name.
// Detect a binding next to self-closing tag end and insert a space to
// separate the marker from the tag end:
const end = regex === tagEndRegex && strings[i + 1].startsWith('/>') ? ' ' : '';
html +=
regex === textEndRegex
? s + nodeMarker
: attrNameEndIndex >= 0
? (attrNames.push(attrName),
s.slice(0, attrNameEndIndex) +
boundAttributeSuffix +
s.slice(attrNameEndIndex)) +
marker +
end
: s +
marker +
(attrNameEndIndex === -2 ? (attrNames.push(undefined), i) : end);
}
const htmlResult = html + (strings[l] || '<?>') + (type === SVG_RESULT$1 ? '</svg>' : '');
// A security check to prevent spoofing of Lit template results.
// In the future, we may be able to replace this with Array.isTemplateObject,
// though we might need to make that check inside of the html and svg
// functions, because precompiled templates don't come in as
// TemplateStringArray objects.
if (!Array.isArray(strings) || !strings.hasOwnProperty('raw')) {
let message = 'invalid template strings array';
throw new Error(message);
}
// Returned as an array for terseness
return [
policy !== undefined
? policy.createHTML(htmlResult)
: htmlResult,
attrNames,
];
};
class Template {
constructor(
// This property needs to remain unminified.
{ strings, ['_$litType$']: type }, options) {
/** @internal */
this.parts = [];
let node;
let nodeIndex = 0;
let attrNameIndex = 0;
const partCount = strings.length - 1;
const parts = this.parts;
// Create template element
const [html, attrNames] = getTemplateHtml(strings, type);
this.el = Template.createElement(html, options);
walker.currentNode = this.el.content;
// Reparent SVG nodes into template root
if (type === SVG_RESULT$1) {
const content = this.el.content;
const svgElement = content.firstChild;
svgElement.remove();
content.append(...svgElement.childNodes);
}
// Walk the template to find binding markers and create TemplateParts
while ((node = walker.nextNode()) !== null && parts.length < partCount) {
if (node.nodeType === 1) {
// TODO (justinfagnani): for attempted dynamic tag names, we don't
// increment the bindingIndex, and it'll be off by 1 in the element
// and off by two after it.
if (node.hasAttributes()) {
// We defer removing bound attributes because on IE we might not be
// iterating attributes in their template order, and would sometimes
// remove an attribute that we still need to create a part for.
const attrsToRemove = [];
for (const name of node.getAttributeNames()) {
// `name` is the name of the attribute we're iterating over, but not
// _neccessarily_ the name of the attribute we will create a part
// for. They can be different in browsers that don't iterate on
// attributes in source order. In that case the attrNames array
// contains the attribute name we'll process next. We only need the
// attribute name here to know if we should process a bound attribute
// on this element.
if (name.endsWith(boundAttributeSuffix) ||
name.startsWith(marker)) {
const realName = attrNames[attrNameIndex++];
attrsToRemove.push(name);
if (realName !== undefined) {
// Lowercase for case-sensitive SVG attributes like viewBox
const value = node.getAttribute(realName.toLowerCase() + boundAttributeSuffix);
const statics = value.split(marker);
const m = /([.?@])?(.*)/.exec(realName);
parts.push({
type: ATTRIBUTE_PART,
index: nodeIndex,
name: m[2],
strings: statics,
ctor: m[1] === '.'
? PropertyPart
: m[1] === '?'
? BooleanAttributePart
: m[1] === '@'
? EventPart
: AttributePart,
});
}
else {
parts.push({
type: ELEMENT_PART,
index: nodeIndex,
});
}
}
}
for (const name of attrsToRemove) {
node.removeAttribute(name);
}
}
// TODO (justinfagnani): benchmark the regex against testing for each
// of the 3 raw text element names.
if (rawTextElement.test(node.tagName)) {
// For raw text elements we need to split the text content on
// markers, create a Text node for each segment, and create
// a TemplatePart for each marker.
const strings = node.textContent.split(marker);
const lastIndex = strings.length - 1;
if (lastIndex > 0) {
node.textContent = trustedTypes
? trustedTypes.emptyScript
: '';
// Generate a new text node for each literal section
// These nodes are also used as the markers for node parts
// We can't use empty text nodes as markers because they're
// normalized when cloning in IE (could simplify when
// IE is no longer supported)
for (let i = 0; i < lastIndex; i++) {
node.append(strings[i], createMarker$1());
// Walk past the marker node we just added
walker.nextNode();
parts.push({ type: CHILD_PART, index: ++nodeIndex });
}
// Note because this marker is added after the walker's current
// node, it will be walked to in the outer loop (and ignored), so
// we don't need to adjust nodeIndex here
node.append(strings[lastIndex], createMarker$1());
}
}
}
else if (node.nodeType === 8) {
const data = node.data;
if (data === markerMatch) {
parts.push({ type: CHILD_PART, index: nodeIndex });
}
else {
let i = -1;
while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
// Comment node has a binding marker inside, make an inactive part
// The binding won't work, but subsequent bindings will
parts.push({ type: COMMENT_PART, index: nodeIndex });
// Move to the end of the match
i += marker.length - 1;
}
}
}
nodeIndex++;
}
}
// Overridden via `litHtmlPolyfillSupport` to provide platform support.
/** @nocollapse */
static createElement(html, _options) {
const doc = __moz_domParser.parseFromString(`<template>${html}</template>`, 'text/html');
return document.importNode(doc.querySelector('template'), true);
}
}
function resolveDirective(part, value, parent = part, attributeIndex) {
var _a, _b, _c;
var _d;
// Bail early if the value is explicitly noChange. Note, this means any
// nested directive is still attached and is not run.
if (value === noChange) {
return value;
}
let currentDirective = attributeIndex !== undefined
? (_a = parent.__directives) === null || _a === void 0 ? void 0 : _a[attributeIndex]
: parent.__directive;
const nextDirectiveConstructor = isPrimitive$1(value)
? undefined
: // This property needs to remain unminified.
value['_$litDirective$'];
if ((currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective.constructor) !== nextDirectiveConstructor) {
// This property needs to remain unminified.
(_b = currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective['_$notifyDirectiveConnectionChanged']) === null || _b === void 0 ? void 0 : _b.call(currentDirective, false);
if (nextDirectiveConstructor === undefined) {
currentDirective = undefined;
}
else {
currentDirective = new nextDirectiveConstructor(part);
currentDirective._$initialize(part, parent, attributeIndex);
}
if (attributeIndex !== undefined) {
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.44 Sekunden
(vorverarbeitet)
]
|
2026-04-02
|