/** * @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), undefined, 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; (_a = this._initializers) !== null && _a !== void 0 ? _a : (this._initializers = []); 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(); 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 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 { * 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.4.1'); /** * @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 `--my-button-color` prop = prop .replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, '-$&') .toLowerCase(); return style + `${prop}:${value};`; }, ''); } update(part, [styleInfo]) { const { style } = part.element; if (this._previousStyleProperties === undefined) { this._previousStyleProperties = new Set(); for (const name in styleInfo) { this._previousStyleProperties.add(name); } return this.render(styleInfo); } // Remove old properties that no longer exist in styleInfo // We use forEach() instead of for-of so that re don't require down-level // iteration. this._previousStyleProperties.forEach((name) => { // If the name isn't in styleInfo or it's null/undefined if (styleInfo[name] == null) { this._previousStyleProperties.delete(name); if (name.includes('-')) { style.removeProperty(name); } else { // Note reset using empty string (vs null) as IE11 does not always // reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles) // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = ''; } } }); // Add or update properties for (const name in styleInfo) { const value = styleInfo[name]; if (value != null) { this._previousStyleProperties.add(name); if (name.includes('-')) { style.setProperty(name, value); } else { // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = value; } } } return noChange; } } /** * A directive that applies CSS properties to an element. * * `styleMap` can only be used in the `style` attribute and must be the only * expression in the attribute. It takes the property names in the * {@link StyleInfo styleInfo} object and adds the property values as CSS * properties. Property names with dashes (`-`) are assumed to be valid CSS * property names and set on the element's style object using `setProperty()`. * Names without dashes are assumed to be camelCased JavaScript property names * and set on the element's style object using property assignment, allowing the * style object to translate JavaScript-style names to CSS property names. * * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size': * '0'})` sets the `background-color`, `border-top` and `--size` properties. * * @param styleInfo * @see {@link https://lit.dev/docs/templates/directives/#stylemap styleMap code samples on Lit.dev} */ const styleMap = directive(StyleMapDirective); /** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ class TemplateContentDirective extends Directive { constructor(partInfo) { super(partInfo); if (partInfo.type !== PartType.CHILD) { throw new Error('templateContent can only be used in child bindings'); } } render(template) { if (this._previousTemplate === template) { return noChange; } this._previousTemplate = template; return document.importNode(template.content, true); } } /** * Renders the content of a template element as HTML. * * Note, the template should be developer controlled and not user controlled. * Rendering a user-controlled template with this directive * could lead to cross-site-scripting vulnerabilities. */ const templateContent = directive(TemplateContentDirective); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const HTML_RESULT = 1; class UnsafeHTMLDirective extends Directive { constructor(partInfo) { super(partInfo); this._value = nothing; if (partInfo.type !== PartType.CHILD) { throw new Error(`${this.constructor.directiveName}() can only be used in child bindings`); } } render(value) { if (value === nothing || value == null) { this._templateResult = undefined; return (this._value = value); } if (value === noChange) { return value; } if (typeof value != 'string') { throw new Error(`${this.constructor.directiveName}() called with a non-string value`); } if (value === this._value) { return this._templateResult; } this._value = value; const strings = [value]; // eslint-disable-next-line @typescript-eslint/no-explicit-any strings.raw = strings; // WARNING: impersonating a TemplateResult like this is extremely // dangerous. Third-party directives should not do this. return (this._templateResult = { // Cast to a known set of integers that satisfy ResultType so that we // don't have to export ResultType and possibly encourage this pattern. // This property needs to remain unminified. ['_$litType$']: this.constructor .resultType, strings, values: [], }); } } UnsafeHTMLDirective.directiveName = 'unsafeHTML'; UnsafeHTMLDirective.resultType = HTML_RESULT; /** * Renders the result as HTML, rather than text. * * The values `undefined`, `null`, and `nothing`, will all result in no content * (empty string) being rendered. * * Note, this is unsafe to use with any user-provided input that hasn't been * sanitized or escaped, as it may lead to cross-site-scripting * vulnerabilities. */ const unsafeHTML = directive(UnsafeHTMLDirective); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const SVG_RESULT = 2; class UnsafeSVGDirective extends UnsafeHTMLDirective { } UnsafeSVGDirective.directiveName = 'unsafeSVG'; UnsafeSVGDirective.resultType = SVG_RESULT; /** * Renders the result as SVG, rather than text. * * The values `undefined`, `null`, and `nothing`, will all result in no content * (empty string) being rendered. * * Note, this is unsafe to use with any user-provided input that hasn't been * sanitized or escaped, as it may lead to cross-site-scripting * vulnerabilities. */ const unsafeSVG = directive(UnsafeSVGDirective); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const isPromise = (x) => { return !isPrimitive(x) && typeof x.then === 'function'; }; // Effectively infinity, but a SMI. const _infinity = 0x3fffffff; class UntilDirective extends AsyncDirective { constructor() { super(...arguments); this.__lastRenderedIndex = _infinity; this.__values = []; this.__weakThis = new PseudoWeakRef(this); this.__pauser = new Pauser(); } render(...args) { var _a; return (_a = args.find((x) => !isPromise(x))) !== null && _a !== void 0 ? _a : noChange; } update(_part, args) { const previousValues = this.__values; let previousLength = previousValues.length; this.__values = args; const weakThis = this.__weakThis; const pauser = this.__pauser; // If our initial render occurs while disconnected, ensure that the pauser // and weakThis are in the disconnected state if (!this.isConnected) { this.disconnected(); } for (let i = 0; i < args.length; i++) { // If we've rendered a higher-priority value already, stop. if (i > this.__lastRenderedIndex) { break; } const value = args[i]; // Render non-Promise values immediately if (!isPromise(value)) { this.__lastRenderedIndex = i; // Since a lower-priority value will never overwrite a higher-priority // synchronous value, we can stop processing now. return value; } // If this is a Promise we've already handled, skip it. if (i < previousLength && value === previousValues[i]) { continue; } // We have a Promise that we haven't seen before, so priorities may have // changed. Forget what we rendered before. this.__lastRenderedIndex = _infinity; previousLength = 0; // Note, the callback avoids closing over `this` so that the directive // can be gc'ed before the promise resolves; instead `this` is retrieved // from `weakThis`, which can break the hard reference in the closure when // the directive disconnects Promise.resolve(value).then(async (result) => { // If we're disconnected, wait until we're (maybe) reconnected // The while loop here handles the case that the connection state // thrashes, causing the pauser to resume and then get re-paused while (pauser.get()) { await pauser.get(); } // If the callback gets here and there is no `this`, it means that the // directive has been disconnected and garbage collected and we don't // need to do anything else const _this = weakThis.deref(); if (_this !== undefined) { const index = _this.__values.indexOf(value); // If state.values doesn't contain the value, we've re-rendered without // the value, so don't render it. Then, only render if the value is // higher-priority than what's already been rendered. if (index > -1 && index < _this.__lastRenderedIndex) { _this.__lastRenderedIndex = index; _this.setValue(result); } } }); } return noChange; } disconnected() { this.__weakThis.disconnect(); this.__pauser.pause(); } reconnected() { this.__weakThis.reconnect(this); this.__pauser.resume(); } } /** * Renders one of a series of values, including Promises, to a Part. * * Values are rendered in priority order, with the first argument having the * highest priority and the last argument having the lowest priority. If a * value is a Promise, low-priority values will be rendered until it resolves. * * The priority of values can be used to create placeholder content for async * data. For example, a Promise with pending content can be the first, * highest-priority, argument, and a non_promise loading indicator template can * be used as the second, lower-priority, argument. The loading indicator will * render immediately, and the primary content will render when the Promise * resolves. * * Example: * * ```js * const content = fetch('./content.txt').then(r => r.text()); * html`${until(content, html`Loading...`)}` * ``` */ const until = directive(UntilDirective); /** * The type of the class that powers this directive. Necessary for naming the * directive's return type. */ // export type {UntilDirective}; /** * @license * Copyright 2021 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ function when(condition, trueCase, falseCase) { return condition ? trueCase() : falseCase === null || falseCase === void 0 ? void 0 : falseCase(); } /** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ /** * Prevents JSON injection attacks. * * The goals of this brand: * 1) fast to check * 2) code is small on the wire * 3) multiple versions of Lit in a single page will all produce mutually * interoperable StaticValues * 4) normal JSON.parse (without an unusual reviver) can not produce a * StaticValue * * Symbols satisfy (1), (2), and (4). We use Symbol.for to satisfy (3), but * we don't care about the key, so we break ties via (2) and use the empty * string. */ const brand = Symbol.for(''); /** Safely extracts the string part of a StaticValue. */ const unwrapStaticValue = (value) => { if ((value === null || value === void 0 ? void 0 : value.r) !== brand) { return undefined; } return value === null || value === void 0 ? void 0 : value['_$litStatic$']; }; /** * Wraps a string so that it behaves like part of the static template * strings instead of a dynamic value. * * Users must take care to ensure that adding the static string to the template * results in well-formed HTML, or else templates may break unexpectedly. * * Note that this function is unsafe to use on untrusted content, as it will be * directly parsed into HTML. Do not pass user input to this function * without sanitizing it. * * Static values can be changed, but they will cause a complete re-render * since they effectively create a new template. */ const unsafeStatic = (value) => ({ ['_$litStatic$']: value, r: brand, }); const textFromStatic = (value) => { if (value['_$litStatic$'] !== undefined) { return value['_$litStatic$']; } else { throw new Error(`Value passed to 'literal' function must be a 'literal' result: ${value}. Use 'unsafeStatic' to pass non-literal values, but take care to ensure page security.`); } }; /** * Tags a string literal so that it behaves like part of the static template * strings instead of a dynamic value. * * The only values that may be used in template expressions are other tagged * `literal` results or `unsafeStatic` values (note that untrusted content * should never be passed to `unsafeStatic`). * * Users must take care to ensure that adding the static string to the template * results in well-formed HTML, or else templates may break unexpectedly. * * Static values can be changed, but they will cause a complete re-render since * they effectively create a new template. */ const literal = (strings, ...values) => ({ ['_$litStatic$']: values.reduce((acc, v, idx) => acc + textFromStatic(v) + strings[idx + 1], strings[0]), r: brand, }); const stringsCache = new Map(); /** * Wraps a lit-html template tag (`html` or `svg`) to add static value support. */ const withStatic = (coreTag) => (strings, ...values) => { const l = values.length; let staticValue; let dynamicValue; const staticStrings = []; const dynamicValues = []; let i = 0; let hasStatics = false; let s; while (i < l) { s = strings[i]; // Collect any unsafeStatic values, and their following template strings // so that we treat a run of template strings and unsafe static values as // a single template string. while (i < l && ((dynamicValue = values[i]), (staticValue = unwrapStaticValue(dynamicValue))) !== undefined) { s += staticValue + strings[++i]; hasStatics = true; } dynamicValues.push(dynamicValue); staticStrings.push(s); i++; } // If the last value isn't static (which would have consumed the last // string), then we need to add the last string. if (i === l) { staticStrings.push(strings[l]); } if (hasStatics) { const key = staticStrings.join('$$lit$$'); strings = stringsCache.get(key); if (strings === undefined) { // Beware: in general this pattern is unsafe, and doing so may bypass // lit's security checks and allow an attacker to execute arbitrary // code and inject arbitrary content. // eslint-disable-next-line @typescript-eslint/no-explicit-any staticStrings.raw = staticStrings; stringsCache.set(key, (strings = staticStrings)); } values = dynamicValues; } return coreTag(strings, ...values); }; /** * Interprets a template literal as an HTML template that can efficiently * render to and update a container. * * Includes static value support from `lit-html/static.js`. */ const html = withStatic(html$1); /** * Interprets a template literal as an SVG template that can efficiently * render to and update a container. * * Includes static value support from `lit-html/static.js`. */ const svg = withStatic(svg$1); /** * @license * Copyright 2021 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ if (!window.litDisableBundleWarning) { console.warn('Lit has been loaded from a bundle that combines all core features into ' + 'a single file. To reduce transfer size and parsing cost, consider ' + 'using the `lit` npm package directly in your project.'); } export { AsyncDirective, AsyncReplaceDirective, CSSResult, Directive, LitElement, PartType, ReactiveElement, TemplateResultType, UnsafeHTMLDirective, UntilDirective, UpdatingElement, _$LE, _$LH, adoptStyles, asyncAppend, asyncReplace, cache, choose, classMap, clearPart, createRef, css, defaultConverter, directive, getCommittedValue, getCompatibleStyle, getDirectiveClass, guard, html$1 as html, ifDefined, insertPart, isDirectiveResult, isPrimitive, isServer, isSingleExpression, isTemplateResult, join, keyed, literal, live, map, noChange, notEqual, nothing, range, ref, removePart, render, repeat, setChildPartValue, setCommittedValue, html as staticHtml, svg as staticSvg, styleMap, supportsAdoptingStyleSheets, svg$1 as svg, templateContent, unsafeCSS, unsafeHTML, unsafeSVG, unsafeStatic, until, when, withStatic }; //# sourceMappingURL=lit-all.min.js.map