Socket
Socket
Sign inDemoInstall

lit-element

Package Overview
Dependencies
Maintainers
11
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lit-element - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0-pre.1

lib/react.d.ts

23

CHANGELOG.md

@@ -13,8 +13,27 @@ # Change Log

<!-- ## Unreleased -->
<!-- ## [x.y.z] - YYYY-MM-DD -->
<!-- ### Changed -->
<!-- ### Added -->
<!-- ### Removed -->
<!-- ### Fixed -->
<!-- ### Changed -->
## [2.3.0-pre.1] - 2020-03-17
### Changed
* Added a static `getPropertyDescriptor` method to allow easier customization of property accessors. This method should return a a `PropertyDescriptor` to install on the property. If no descriptor is returned, a property accessor is not be created. ([#911](https://github.com/Polymer/lit-element/issues/911))
* The value returned by `render` is always rendered, even if it isn't a `TemplateResult`. ([#712](https://github.com/Polymer/lit-element/issues/712))
### Added
* Added `@queryAsync(selector)` decorator which returns a Promise that resolves to the result of querying for the given selector after the element's `updateComplete` Promise resolves ([#903](https://github.com/Polymer/lit-element/issues/903)).
* Added `enableUpdating()` to `UpdatingElement` to enable customizing when updating is enabled [#860](https://github.com/Polymer/lit-element/pull/860).
* Added `queryAssignedNodes(slotName, flatten)` to enable querying assignedNodes for a given slot [#860](https://github.com/Polymer/lit-element/pull/860).
* Added `getStyles()` to `LitElement` to allow hooks into style gathering for component sets [#866](https://github.com/Polymer/lit-element/pull/866).
### Fixed
* Ensure `UpdatingElement` allows updates when properties are set after calling `super.update()`.
`LitElement` renders when updates are triggered as a result of rendering ([#549](https://github.com/Polymer/lit-element/issues/549)).
* Properties annotated with the `eventOptions` decorator will now survive property renaming optimizations when used with tsickle and Closure JS Compiler.
* Moved style gathering from `finalize` to `initialize` to be more lazy, and create stylesheets on the first instance initializing [#866](https://github.com/Polymer/lit-element/pull/866).
* Fixed behavior change for components that do not implement `render()` introduced in ([#712](https://github.com/Polymer/lit-element/pull/712)) ([#917](https://github.com/Polymer/lit-element/pull/917))
## [2.2.1] - 2019-07-23

@@ -21,0 +40,0 @@ ### Changed

2

lib/css-tag.d.ts

@@ -16,3 +16,3 @@ /**

constructor(cssText: string, safeToken: symbol);
readonly styleSheet: CSSStyleSheet | null;
get styleSheet(): CSSStyleSheet | null;
toString(): string;

@@ -19,0 +19,0 @@ }

@@ -16,3 +16,3 @@ /**

export declare type Constructor<T> = {
new (...args: unknown[]): T;
new (...args: any[]): T;
};

@@ -36,3 +36,12 @@ interface ClassDescriptor {

*
* @param tagName the name of the custom element to define
* ```
* @customElement('my-element')
* class MyElement {
* render() {
* return html``;
* }
* }
* ```
*
* @param tagName The name of the custom element to define.
*/

@@ -45,17 +54,109 @@ export declare const customElement: (tagName: string) => (classOrDescriptor: ClassDescriptor | Constructor<HTMLElement>) => any;

*
* This decorator should only be used for public fields. Private or protected
* fields should use the internalProperty decorator.
*
* @example
*
* class MyElement {
* @property({ type: Boolean })
* clicked = false;
* }
*
* @ExportDecoratedItems
*/
export declare function property(options?: PropertyDeclaration): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;
export interface InternalPropertyDeclaration<Type = unknown> {
/**
* A function that indicates if a property should be considered changed when
* it is set. The function should take the `newValue` and `oldValue` and
* return `true` if an update should be requested.
*/
hasChanged?(value: Type, oldValue: Type): boolean;
}
/**
* Declares a private or protected property that still triggers updates to the
* element when it changes.
*
* Properties declared this way must not be used from HTML or HTML templating
* systems, they're solely for properties internal to the element. These
* properties may be renamed by optimization tools like closure compiler.
*/
export declare function internalProperty(options?: InternalPropertyDeclaration): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;
/**
* A property decorator that converts a class property into a getter that
* executes a querySelector on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @query('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
*/
export declare function query(selector: string): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;
/**
* A property decorator that converts a class property into a getter that
* returns a promise that resolves to the result of a querySelector on the
* element's renderRoot done after the element's `updateComplete` promise
* resolves. When the queried property may change with element state, this
* decorator can be used instead of requiring users to await the
* `updateComplete` before accessing the property.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @queryAsync('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
* // external usage
* async doSomethingWithFirst() {
* (await aMyElement.first).doSomething();
* }
*/
export declare function queryAsync(selector: string): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;
/**
* A property decorator that converts a class property into a getter
* that executes a querySelectorAll on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
*
* @example
*
* class MyElement {
* @queryAll('div')
* divs;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*/

@@ -67,3 +168,3 @@ export declare function queryAll(selector: string): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;

*
* @param options An object that specifis event listener options as accepted by
* @param options An object that specifies event listener options as accepted by
* `EventTarget#addEventListener` and `EventTarget#removeEventListener`.

@@ -77,7 +178,10 @@ *

* class MyElement {
*
* clicked = false;
*
* render() {
* return html`<div @click=${this._onClick}`><button></button></div>`;
* return html`
* <div @click=${this._onClick}`>
* <button></button>
* </div>
* `;
* }

@@ -91,4 +195,11 @@ *

*/
export declare const eventOptions: (options: AddEventListenerOptions) => any;
export declare function eventOptions(options: AddEventListenerOptions): any;
/**
* A property decorator that converts a class property into a getter that
* returns the `assignedNodes` of the given named `slot`. Note, the type of
* this property should be annotated as `NodeListOf<HTMLElement>`.
*
*/
export declare function queryAssignedNodes(slotName?: string, flatten?: boolean): (protoOrDescriptor: Object | ClassElement, name?: string | number | symbol | undefined) => any;
export {};
//# sourceMappingURL=decorators.d.ts.map

@@ -38,3 +38,12 @@ /**

*
* @param tagName the name of the custom element to define
* ```
* @customElement('my-element')
* class MyElement {
* render() {
* return html``;
* }
* }
* ```
*
* @param tagName The name of the custom element to define.
*/

@@ -50,3 +59,3 @@ export const customElement = (tagName) => (classOrDescriptor) => (typeof classOrDescriptor === 'function') ?

!('value' in element.descriptor)) {
return Object.assign({}, element, { finisher(clazz) {
return Object.assign(Object.assign({}, element), { finisher(clazz) {
clazz.createProperty(element.key, options);

@@ -93,2 +102,12 @@ } });

*
* This decorator should only be used for public fields. Private or protected
* fields should use the internalProperty decorator.
*
* @example
*
* class MyElement {
* @property({ type: Boolean })
* clicked = false;
* }
*
* @ExportDecoratedItems

@@ -103,6 +122,34 @@ */

/**
* Declares a private or protected property that still triggers updates to the
* element when it changes.
*
* Properties declared this way must not be used from HTML or HTML templating
* systems, they're solely for properties internal to the element. These
* properties may be renamed by optimization tools like closure compiler.
*/
export function internalProperty(options) {
return property({ attribute: false, hasChanged: options === null || options === void 0 ? void 0 : options.hasChanged });
}
/**
* A property decorator that converts a class property into a getter that
* executes a querySelector on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @query('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
*/

@@ -125,7 +172,76 @@ export function query(selector) {

}
// Note, in the future, we may extend this decorator to support the use case
// where the queried element may need to do work to become ready to interact
// with (e.g. load some implementation code). If so, we might elect to
// add a second argument defining a function that can be run to make the
// queried element loaded/updated/ready.
/**
* A property decorator that converts a class property into a getter that
* returns a promise that resolves to the result of a querySelector on the
* element's renderRoot done after the element's `updateComplete` promise
* resolves. When the queried property may change with element state, this
* decorator can be used instead of requiring users to await the
* `updateComplete` before accessing the property.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @queryAsync('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
* // external usage
* async doSomethingWithFirst() {
* (await aMyElement.first).doSomething();
* }
*/
export function queryAsync(selector) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
async get() {
await this.updateComplete;
return this.renderRoot.querySelector(selector);
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
/**
* A property decorator that converts a class property into a getter
* that executes a querySelectorAll on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
*
* @example
*
* class MyElement {
* @queryAll('div')
* divs;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*/

@@ -158,3 +274,3 @@ export function queryAll(selector) {

const standardEventOptions = (options, element) => {
return Object.assign({}, element, { finisher(clazz) {
return Object.assign(Object.assign({}, element), { finisher(clazz) {
Object.assign(clazz.prototype[element.key], options);

@@ -172,3 +288,3 @@ } });

*
* @param options An object that specifis event listener options as accepted by
* @param options An object that specifies event listener options as accepted by
* `EventTarget#addEventListener` and `EventTarget#removeEventListener`.

@@ -182,7 +298,10 @@ *

* class MyElement {
*
* clicked = false;
*
* render() {
* return html`<div @click=${this._onClick}`><button></button></div>`;
* return html`
* <div @click=${this._onClick}`>
* <button></button>
* </div>
* `;
* }

@@ -196,11 +315,36 @@ *

*/
export const eventOptions = (options) =>
// Return value typed as any to prevent TypeScript from complaining that
// standard decorator function signature does not match TypeScript decorator
// signature
// TODO(kschaaf): unclear why it was only failing on this decorator and not
// the others
((protoOrDescriptor, name) => (name !== undefined) ?
legacyEventOptions(options, protoOrDescriptor, name) :
standardEventOptions(options, protoOrDescriptor));
export function eventOptions(options) {
// Return value typed as any to prevent TypeScript from complaining that
// standard decorator function signature does not match TypeScript decorator
// signature
// TODO(kschaaf): unclear why it was only failing on this decorator and not
// the others
return ((protoOrDescriptor, name) => (name !== undefined) ?
legacyEventOptions(options, protoOrDescriptor, name) :
standardEventOptions(options, protoOrDescriptor));
}
/**
* A property decorator that converts a class property into a getter that
* returns the `assignedNodes` of the given named `slot`. Note, the type of
* this property should be annotated as `NodeListOf<HTMLElement>`.
*
*/
export function queryAssignedNodes(slotName = '', flatten = false) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
get() {
const selector = `slot${slotName ? `[name=${slotName}]` : ''}`;
const slot = this.renderRoot.querySelector(selector);
return slot && slot.assignedNodes({ flatten });
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
//# sourceMappingURL=decorators.js.map

@@ -38,3 +38,3 @@ /**

}
declare type AttributeConverter<Type = unknown, TypeHint = unknown> = ComplexAttributeConverter<Type> | ((value: string, type?: TypeHint) => Type);
declare type AttributeConverter<Type = unknown, TypeHint = unknown> = ComplexAttributeConverter<Type> | ((value: string | null, type?: TypeHint) => Type);
/**

@@ -103,3 +103,7 @@ * Defines options for a property accessor.

}
export declare type PropertyValues = Map<PropertyKey, unknown>;
/**
* Map of changed properties with old values. Takes an optional generic
* interface corresponding to the declared element properties.
*/
export declare type PropertyValues<T = any> = keyof T extends PropertyKey ? Map<keyof T, unknown> : never;
export declare const defaultConverter: ComplexAttributeConverter;

@@ -151,3 +155,3 @@ export interface HasChanged {

*/
static readonly observedAttributes: string[];
static get observedAttributes(): string[];
/**

@@ -161,6 +165,21 @@ * Ensures the private `_classProperties` property metadata is created.

/**
* Creates a property accessor on the element prototype if one does not exist.
* Creates a property accessor on the element prototype if one does not exist
* and stores a 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:
*
* static createProperty(name, options) {
* options = Object.assign(options, {myOption: true});
* super.createProperty(name, options);
* }
*
* @nocollapse

@@ -170,2 +189,44 @@ */

/**
* 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,
*
* 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
*/
protected static getPropertyDescriptor(name: PropertyKey, key: string | symbol, _options: PropertyDeclaration): {
get(): any;
set(this: UpdatingElement, value: unknown): void;
configurable: boolean;
enumerable: boolean;
};
/**
* 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 `createProperty`.
*
* @nocollapse
* @final
*/
protected static getPropertyOptions(name: PropertyKey): PropertyDeclaration<unknown, unknown>;
/**
* Creates property accessors for registered properties and ensures

@@ -207,3 +268,3 @@ * any superclasses are also finalized.

private _updatePromise;
private _hasConnectedResolver;
private _enableUpdatingResolver;
/**

@@ -242,2 +303,3 @@ * Map with keys for any properties that have changed since the last

connectedCallback(): void;
protected enableUpdating(): void;
/**

@@ -279,5 +341,4 @@ * Allows for `super.disconnectedCallback()` in extensions while

private _enqueueUpdate;
private readonly _hasConnected;
private readonly _hasRequestedUpdate;
protected readonly hasUpdated: number;
private get _hasRequestedUpdate();
protected get hasUpdated(): number;
/**

@@ -316,3 +377,3 @@ * Performs an element update. Note, if an exception is thrown during the

*/
readonly updateComplete: Promise<unknown>;
get updateComplete(): Promise<unknown>;
/**

@@ -340,3 +401,3 @@ * Override point for the `updateComplete` promise.

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -350,3 +411,3 @@ protected shouldUpdate(_changedProperties: PropertyValues): boolean;

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -361,3 +422,3 @@ protected update(_changedProperties: PropertyValues): void;

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -372,3 +433,3 @@ protected updated(_changedProperties: PropertyValues): void;

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -375,0 +436,0 @@ protected firstUpdated(_changedProperties: PropertyValues): void;

@@ -64,3 +64,2 @@ /**

};
const microtaskPromise = Promise.resolve(true);
const STATE_HAS_UPDATED = 1;

@@ -70,3 +69,2 @@ const STATE_UPDATE_REQUESTED = 1 << 2;

const STATE_IS_REFLECTING_TO_PROPERTY = 1 << 4;
const STATE_HAS_CONNECTED = 1 << 5;
/**

@@ -89,4 +87,5 @@ * The Closure JS Compiler doesn't currently have good support for static

this._instanceProperties = undefined;
this._updatePromise = microtaskPromise;
this._hasConnectedResolver = undefined;
// Initialize to an unresolved Promise so we can make sure the element has
// connected before first update.
this._updatePromise = new Promise((res) => this._enableUpdatingResolver = res);
/**

@@ -140,6 +139,21 @@ * Map with keys for any properties that have changed since the last

/**
* Creates a property accessor on the element prototype if one does not exist.
* Creates a property accessor on the element prototype if one does not exist
* and stores a 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:
*
* static createProperty(name, options) {
* options = Object.assign(options, {myOption: true});
* super.createProperty(name, options);
* }
*
* @nocollapse

@@ -162,3 +176,32 @@ */

const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
Object.defineProperty(this.prototype, 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,
*
* 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
*/
static getPropertyDescriptor(name, key, _options) {
return {
// tslint:disable-next-line:no-any no symbol in index

@@ -175,5 +218,21 @@ get() {

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 `createProperty`.
*
* @nocollapse
* @final
*/
static getPropertyOptions(name) {
return this._classProperties && this._classProperties.get(name) ||
defaultPropertyDeclaration;
}
/**
* Creates property accessors for registered properties and ensures

@@ -314,10 +373,10 @@ * any superclasses are also finalized.

connectedCallback() {
this._updateState = this._updateState | STATE_HAS_CONNECTED;
// Ensure first connection completes an update. Updates cannot complete
// before connection and if one is pending connection the
// `_hasConnectionResolver` will exist. If so, resolve it to complete the
// update, otherwise requestUpdate.
if (this._hasConnectedResolver) {
this._hasConnectedResolver();
this._hasConnectedResolver = undefined;
// before connection.
this.enableUpdating();
}
enableUpdating() {
if (this._enableUpdatingResolver !== undefined) {
this._enableUpdatingResolver();
this._enableUpdatingResolver = undefined;
}

@@ -375,5 +434,8 @@ }

const ctor = this.constructor;
// Note, hint this as an `AttributeMap` so closure clearly understands
// the type; it has issues with tracking types through statics
// tslint:disable-next-line:no-unnecessary-type-assertion
const propName = ctor._attributeToPropertyMap.get(name);
if (propName !== undefined) {
const options = ctor._classProperties.get(propName) || defaultPropertyDeclaration;
const options = ctor.getPropertyOptions(propName);
// mark state reflecting

@@ -398,3 +460,3 @@ this._updateState = this._updateState | STATE_IS_REFLECTING_TO_PROPERTY;

const ctor = this.constructor;
const options = ctor._classProperties.get(name) || defaultPropertyDeclaration;
const options = ctor.getPropertyOptions(name);
if (ctor._valueHasChanged(this[name], oldValue, options.hasChanged)) {

@@ -422,3 +484,3 @@ if (!this._changedProperties.has(name)) {

if (!this._hasRequestedUpdate && shouldRequestUpdate) {
this._enqueueUpdate();
this._updatePromise = this._enqueueUpdate();
}

@@ -447,15 +509,7 @@ }

async _enqueueUpdate() {
// Mark state updating...
this._updateState = this._updateState | STATE_UPDATE_REQUESTED;
let resolve;
let reject;
const previousUpdatePromise = this._updatePromise;
this._updatePromise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
try {
// Ensure any previous update has resolved before updating.
// This `await` also ensures that property changes are batched.
await previousUpdatePromise;
await this._updatePromise;
}

@@ -466,23 +520,11 @@ catch (e) {

}
// Make sure the element has connected before updating.
if (!this._hasConnected) {
await new Promise((res) => this._hasConnectedResolver = res);
const result = this.performUpdate();
// If `performUpdate` 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;
}
try {
const result = this.performUpdate();
// If `performUpdate` 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;
}
}
catch (e) {
reject(e);
}
resolve(!this._hasRequestedUpdate);
return !this._hasRequestedUpdate;
}
get _hasConnected() {
return (this._updateState & STATE_HAS_CONNECTED);
}
get _hasRequestedUpdate() {

@@ -522,2 +564,5 @@ return (this._updateState & STATE_UPDATE_REQUESTED);

}
else {
this._markUpdated();
}
}

@@ -528,7 +573,5 @@ catch (e) {

shouldUpdate = false;
throw e;
}
finally {
// Ensure element can accept additional updates after an exception.
this._markUpdated();
throw e;
}

@@ -589,3 +632,3 @@ if (shouldUpdate) {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -601,3 +644,3 @@ shouldUpdate(_changedProperties) {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -612,2 +655,3 @@ update(_changedProperties) {

}
this._markUpdated();
}

@@ -621,3 +665,3 @@ /**

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -633,3 +677,3 @@ updated(_changedProperties) {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -636,0 +680,0 @@ firstUpdated(_changedProperties) {

@@ -14,3 +14,3 @@ /**

*/
import { TemplateResult } from 'lit-html';
import { ShadyRenderOptions } from 'lit-html/lib/shady-render.js';
import { PropertyValues, UpdatingElement } from './lib/updating-element.js';

@@ -39,10 +39,9 @@ export * from './lib/updating-element.js';

/**
* Render method used to render the lit-html TemplateResult to the element's
* DOM.
* @param {TemplateResult} Template to render.
* @param {Element|DocumentFragment} Node into which to render.
* @param {String} Element name.
* Render method used to render the value to the element's DOM.
* @param result The value to render.
* @param container Node into which to render.
* @param options Element name.
* @nocollapse
*/
static render: (result: TemplateResult, container: Element | DocumentFragment | ShadowRoot, options: import("lit-html/lib/shady-render").ShadyRenderOptions) => void;
static render: (result: unknown, container: Element | DocumentFragment, options: ShadyRenderOptions) => void;
/**

@@ -54,5 +53,10 @@ * Array of styles to apply to the element. The styles should be defined

private static _styles;
/**
* Return the array of styles to apply to the element.
* Override this method to integrate into a style management system.
*
* @nocollapse
*/
static getStyles(): CSSResult | CSSResultArray | undefined;
/** @nocollapse */
protected static finalize(): void;
/** @nocollapse */
private static _getUniqueStyles;

@@ -94,12 +98,13 @@ private _needsShimAdoptedStyleSheets?;

* this method will *not* trigger another update.
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/
protected update(changedProperties: PropertyValues): void;
/**
* Invoked on each update to perform rendering tasks. This method must return
* a lit-html TemplateResult. Setting properties inside this method will *not*
* trigger the element to update.
* Invoked on each update to perform rendering tasks. This method may return
* any value renderable by lit-html's NodePart - typically a TemplateResult.
* Setting properties inside this method will *not* trigger the element to
* update.
*/
protected render(): TemplateResult | void;
protected render(): unknown;
}
//# sourceMappingURL=lit-element.d.ts.map

@@ -14,3 +14,2 @@ /**

*/
import { TemplateResult } from 'lit-html';
import { render } from 'lit-html/lib/shady-render.js';

@@ -27,39 +26,26 @@ import { UpdatingElement } from './lib/updating-element.js';

(window['litElementVersions'] || (window['litElementVersions'] = []))
.push('2.2.1');
.push('2.3.0-pre.1');
/**
* Minimal implementation of Array.prototype.flat
* @param arr the array to flatten
* @param result the accumlated result
* Sentinal value used to avoid calling lit-html's render function when
* subclasses do not implement `render`
*/
function arrayFlat(styles, result = []) {
for (let i = 0, length = styles.length; i < length; i++) {
const value = styles[i];
if (Array.isArray(value)) {
arrayFlat(value, result);
}
else {
result.push(value);
}
}
return result;
}
/** Deeply flattens styles array. Uses native flat if available. */
const flattenStyles = (styles) => styles.flat ? styles.flat(Infinity) : arrayFlat(styles);
const renderNotImplemented = {};
export class LitElement extends UpdatingElement {
/** @nocollapse */
static finalize() {
// The Closure JS Compiler does not always preserve the correct "this"
// when calling static super methods (b/137460243), so explicitly bind.
super.finalize.call(this);
// Prepare styling that is stamped at first render time. Styling
// is built from user provided `styles` or is inherited from the superclass.
this._styles =
this.hasOwnProperty(JSCompiler_renameProperty('styles', this)) ?
this._getUniqueStyles() :
this._styles || [];
/**
* Return the array of styles to apply to the element.
* Override this method to integrate into a style management system.
*
* @nocollapse
*/
static getStyles() {
return this.styles;
}
/** @nocollapse */
static _getUniqueStyles() {
// Take care not to call `this.styles` multiple times since this generates
// new CSSResults each time.
// Only gather styles once per class
if (this.hasOwnProperty(JSCompiler_renameProperty('_styles', this))) {
return;
}
// Take care not to call `this.getStyles()` multiple times since this
// generates new CSSResults each time.
// TODO(sorvell): Since we do not cache CSSResults by input, any

@@ -69,23 +55,26 @@ // shared styles will generate new stylesheet objects, which is wasteful.

// stylesheets.
const userStyles = this.styles;
const styles = [];
if (Array.isArray(userStyles)) {
const flatStyles = flattenStyles(userStyles);
// As a performance optimization to avoid duplicated styling that can
// occur especially when composing via subclassing, de-duplicate styles
// preserving the last item in the list. The last item is kept to
// try to preserve cascade order with the assumption that it's most
// important that last added styles override previous styles.
const styleSet = flatStyles.reduceRight((set, s) => {
set.add(s);
// on IE set.add does not return the set.
return set;
}, new Set());
// Array.from does not work on Set in IE
styleSet.forEach((v) => styles.unshift(v));
const userStyles = this.getStyles();
if (userStyles === undefined) {
this._styles = [];
}
else if (userStyles) {
styles.push(userStyles);
else if (Array.isArray(userStyles)) {
// De-duplicate styles preserving the _last_ instance in the set.
// 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.
const addStyles = (styles, set) => styles.reduceRight((set, s) =>
// Note: On IE set.add() does not return the set
Array.isArray(s) ? addStyles(s, set) : (set.add(s), set), set);
// Array.from does not work on Set in IE, otherwise return
// Array.from(addStyles(userStyles, new Set<CSSResult>())).reverse()
const set = addStyles(userStyles, new Set());
const styles = [];
set.forEach((v) => styles.unshift(v));
this._styles = styles;
}
return styles;
else {
this._styles = [userStyles];
}
}

@@ -99,2 +88,3 @@ /**

super.initialize();
this.constructor._getUniqueStyles();
this.renderRoot =

@@ -163,8 +153,12 @@ this.createRenderRoot();

* this method will *not* trigger another update.
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/
update(changedProperties) {
// Setting properties in `render` should not trigger an update. Since
// updates are allowed after super.update, it's important to call `render`
// before that.
const templateResult = this.render();
super.update(changedProperties);
const templateResult = this.render();
if (templateResult instanceof TemplateResult) {
// If render is not implemented by the component, don't call lit-html render
if (templateResult !== renderNotImplemented) {
this.constructor

@@ -186,7 +180,9 @@ .render(templateResult, this.renderRoot, { scopeName: this.localName, eventContext: this });

/**
* Invoked on each update to perform rendering tasks. This method must return
* a lit-html TemplateResult. Setting properties inside this method will *not*
* trigger the element to update.
* Invoked on each update to perform rendering tasks. This method may return
* any value renderable by lit-html's NodePart - typically a TemplateResult.
* Setting properties inside this method will *not* trigger the element to
* update.
*/
render() {
return renderNotImplemented;
}

@@ -203,7 +199,6 @@ }

/**
* Render method used to render the lit-html TemplateResult to the element's
* DOM.
* @param {TemplateResult} Template to render.
* @param {Element|DocumentFragment} Node into which to render.
* @param {String} Element name.
* Render method used to render the value to the element's DOM.
* @param result The value to render.
* @param container Node into which to render.
* @param options Element name.
* @nocollapse

@@ -210,0 +205,0 @@ */

{
"name": "lit-element",
"version": "2.2.1",
"version": "2.3.0-pre.1",
"description": "A simple base class for creating fast, lightweight web components",

@@ -50,12 +50,12 @@ "license": "BSD-3-Clause",

"lit-element-benchmarks": "^0.1.0",
"mocha": "^5.0.5",
"np": "^4.0.2",
"rollup": "^0.64.1",
"rollup-plugin-filesize": "^4.0.1",
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-terser": "^1.0.1",
"tachometer": "^0.4.4",
"tslint": "^5.12.0",
"mocha": "^6.2.2",
"np": "^5.2.1",
"rollup": "^1.26.0",
"rollup-plugin-filesize": "^6.2.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^5.1.0",
"tachometer": "^0.4.16",
"tslint": "^5.20.1",
"typedoc": "^0.14.2",
"typescript": "^3.4.1",
"typescript": "^3.8.2",
"uglify-es": "^3.3.9",

@@ -67,3 +67,3 @@ "wct-mocha": "^1.0.0",

"dependencies": {
"lit-html": "^1.0.0"
"lit-html": "^1.1.1"
},

@@ -70,0 +70,0 @@ "publishConfig": {

@@ -6,4 +6,6 @@ # LitElement

[![Published on npm](https://img.shields.io/npm/v/lit-element.svg)](https://www.npmjs.com/package/lit-element)
[![Join our Slack](https://img.shields.io/badge/slack-join%20chat-4a154b.svg)](https://www.polymer-project.org/slack-invite)
[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/lit-element)
[![Mentioned in Awesome lit-html](https://awesome.re/mentioned-badge.svg)](https://github.com/web-padawan/awesome-lit-html)
[![BrowserStack Status](https://automate.browserstack.com/badge.svg?badge_key=TnM4R3dScWdhU1NRck1WejNtMmVoMzQrU2s5bnRtOVVGMmFkQWtEV25iST0tLTNiWEZVYldaV1VqY2oxTEVJV09XSFE9PQ==--e79a2e8601a562e5b200dfcd2d6a15416fd4ed5f)](https://automate.browserstack.com/public-build/TnM4R3dScWdhU1NRck1WejNtMmVoMzQrU2s5bnRtOVVGMmFkQWtEV25iST0tLTNiWEZVYldaV1VqY2oxTEVJV09XSFE9PQ==--e79a2e8601a562e5b200dfcd2d6a15416fd4ed5f)

@@ -86,2 +88,2 @@ ## Documentation

Please see [CONTRIBUTING.md](./CONTRIBUTING.md).
Please see [CONTRIBUTING.md](./CONTRIBUTING.md).
interface ShadyCSS {
styleElement(host: Element, overrideProps?: {[key: string]: string}): void;
getComputedStyleValue(element: Element, property: string): string;
ScopingShim: undefined|{prepareAdoptedCssText(cssText: string[], name: string): void;};
ScopingShim: undefined|{
prepareAdoptedCssText(cssText: string[], name: string): void;
};
nativeShadow: boolean;

@@ -10,2 +12,3 @@ }

inUse: boolean;
flush: () => void;
}

@@ -12,0 +15,0 @@

@@ -15,2 +15,9 @@ /**

/**
* IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all
* property decorators (but not class decorators) in this file that have
* an @ExportDecoratedItems annotation must be defined as a regular function,
* not an arrow function.
*/
import {LitElement} from '../lit-element.js';

@@ -21,3 +28,4 @@

export type Constructor<T> = {
new (...args: unknown[]): T
// tslint:disable-next-line:no-any
new (...args: any[]): T
};

@@ -71,3 +79,12 @@

*
* @param tagName the name of the custom element to define
* ```
* @customElement('my-element')
* class MyElement {
* render() {
* return html``;
* }
* }
* ```
*
* @param tagName The name of the custom element to define.
*/

@@ -134,2 +151,12 @@ export const customElement = (tagName: string) =>

*
* This decorator should only be used for public fields. Private or protected
* fields should use the internalProperty decorator.
*
* @example
*
* class MyElement {
* @property({ type: Boolean })
* clicked = false;
* }
*
* @ExportDecoratedItems

@@ -145,7 +172,45 @@ */

export interface InternalPropertyDeclaration<Type = unknown> {
/**
* A function that indicates if a property should be considered changed when
* it is set. The function should take the `newValue` and `oldValue` and
* return `true` if an update should be requested.
*/
hasChanged?(value: Type, oldValue: Type): boolean;
}
/**
* Declares a private or protected property that still triggers updates to the
* element when it changes.
*
* Properties declared this way must not be used from HTML or HTML templating
* systems, they're solely for properties internal to the element. These
* properties may be renamed by optimization tools like closure compiler.
*/
export function internalProperty(options?: InternalPropertyDeclaration) {
return property({attribute: false, hasChanged: options?.hasChanged});
}
/**
* A property decorator that converts a class property into a getter that
* executes a querySelector on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @query('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
*/

@@ -169,7 +234,77 @@ export function query(selector: string) {

// Note, in the future, we may extend this decorator to support the use case
// where the queried element may need to do work to become ready to interact
// with (e.g. load some implementation code). If so, we might elect to
// add a second argument defining a function that can be run to make the
// queried element loaded/updated/ready.
/**
* A property decorator that converts a class property into a getter that
* returns a promise that resolves to the result of a querySelector on the
* element's renderRoot done after the element's `updateComplete` promise
* resolves. When the queried property may change with element state, this
* decorator can be used instead of requiring users to await the
* `updateComplete` before accessing the property.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @queryAsync('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
* // external usage
* async doSomethingWithFirst() {
* (await aMyElement.first).doSomething();
* }
*/
export function queryAsync(selector: string) {
return (protoOrDescriptor: Object|ClassElement,
// tslint:disable-next-line:no-any decorator
name?: PropertyKey): any => {
const descriptor = {
async get(this: LitElement) {
await this.updateComplete;
return this.renderRoot.querySelector(selector);
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor as Object, name) :
standardQuery(descriptor, protoOrDescriptor as ClassElement);
};
}
/**
* A property decorator that converts a class property into a getter
* that executes a querySelectorAll on the element's renderRoot.
*
* @ExportDecoratedItems
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
*
* @example
*
* class MyElement {
* @queryAll('div')
* divs;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*/

@@ -227,3 +362,3 @@ export function queryAll(selector: string) {

*
* @param options An object that specifis event listener options as accepted by
* @param options An object that specifies event listener options as accepted by
* `EventTarget#addEventListener` and `EventTarget#removeEventListener`.

@@ -237,7 +372,10 @@ *

* class MyElement {
*
* clicked = false;
*
* render() {
* return html`<div @click=${this._onClick}`><button></button></div>`;
* return html`
* <div @click=${this._onClick}`>
* <button></button>
* </div>
* `;
* }

@@ -251,13 +389,41 @@ *

*/
export const eventOptions = (options: AddEventListenerOptions) =>
// Return value typed as any to prevent TypeScript from complaining that
// standard decorator function signature does not match TypeScript decorator
// signature
// TODO(kschaaf): unclear why it was only failing on this decorator and not
// the others
((protoOrDescriptor: Object|ClassElement, name?: string) =>
(name !== undefined) ?
legacyEventOptions(options, protoOrDescriptor as Object, name) :
standardEventOptions(options, protoOrDescriptor as ClassElement)) as
// tslint:disable-next-line:no-any decorator
any;
export function eventOptions(options: AddEventListenerOptions) {
// Return value typed as any to prevent TypeScript from complaining that
// standard decorator function signature does not match TypeScript decorator
// signature
// TODO(kschaaf): unclear why it was only failing on this decorator and not
// the others
return ((protoOrDescriptor: Object|ClassElement, name?: string) =>
(name !== undefined) ?
legacyEventOptions(options, protoOrDescriptor as Object, name) :
standardEventOptions(
options, protoOrDescriptor as ClassElement)) as
// tslint:disable-next-line:no-any decorator
any;
}
/**
* A property decorator that converts a class property into a getter that
* returns the `assignedNodes` of the given named `slot`. Note, the type of
* this property should be annotated as `NodeListOf<HTMLElement>`.
*
*/
export function queryAssignedNodes(
slotName: string = '', flatten: boolean = false) {
return (protoOrDescriptor: Object|ClassElement,
// tslint:disable-next-line:no-any decorator
name?: PropertyKey): any => {
const descriptor = {
get(this: LitElement) {
const selector = `slot${slotName ? `[name=${slotName}]` : ''}`;
const slot = this.renderRoot.querySelector(selector);
return slot && (slot as HTMLSlotElement).assignedNodes({flatten});
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor as Object, name) :
standardQuery(descriptor, protoOrDescriptor as ClassElement);
};
}

@@ -54,3 +54,3 @@ /**

type AttributeConverter<Type = unknown, TypeHint = unknown> =
ComplexAttributeConverter<Type>|((value: string, type?: TypeHint) => Type);
ComplexAttributeConverter<Type>|((value: string|null, type?: TypeHint) => Type);

@@ -116,2 +116,3 @@ /**

readonly noAccessor?: boolean;
}

@@ -132,3 +133,9 @@

export type PropertyValues = Map<PropertyKey, unknown>;
/**
* Map of changed properties with old values. Takes an optional generic
* interface corresponding to the declared element properties.
*/
// tslint:disable-next-line:no-any
export type PropertyValues<T = any> =
keyof T extends PropertyKey ? Map<keyof T, unknown>: never;

@@ -186,4 +193,2 @@ export const defaultConverter: ComplexAttributeConverter = {

const microtaskPromise = Promise.resolve(true);
const STATE_HAS_UPDATED = 1;

@@ -193,6 +198,5 @@ const STATE_UPDATE_REQUESTED = 1 << 2;

const STATE_IS_REFLECTING_TO_PROPERTY = 1 << 4;
const STATE_HAS_CONNECTED = 1 << 5;
type UpdateState = typeof STATE_HAS_UPDATED|typeof STATE_UPDATE_REQUESTED|
typeof STATE_IS_REFLECTING_TO_ATTRIBUTE|
typeof STATE_IS_REFLECTING_TO_PROPERTY|typeof STATE_HAS_CONNECTED;
typeof STATE_IS_REFLECTING_TO_PROPERTY;

@@ -286,6 +290,21 @@ /**

/**
* Creates a property accessor on the element prototype if one does not exist.
* Creates a property accessor on the element prototype if one does not exist
* and stores a 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:
*
* static createProperty(name, options) {
* options = Object.assign(options, {myOption: true});
* super.createProperty(name, options);
* }
*
* @nocollapse

@@ -310,3 +329,34 @@ */

const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
Object.defineProperty(this.prototype, 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,
*
* 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
*/
protected static getPropertyDescriptor(name: PropertyKey,
key: string|symbol, _options: PropertyDeclaration) {
return {
// tslint:disable-next-line:no-any no symbol in index

@@ -324,6 +374,23 @@ get(): any {

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 `createProperty`.
*
* @nocollapse
* @final
*/
protected static getPropertyOptions(name: PropertyKey) {
return this._classProperties && this._classProperties.get(name) ||
defaultPropertyDeclaration;
}
/**
* Creates property accessors for registered properties and ensures

@@ -429,4 +496,7 @@ * any superclasses are also finalized.

private _instanceProperties: PropertyValues|undefined = undefined;
private _updatePromise: Promise<unknown> = microtaskPromise;
private _hasConnectedResolver: (() => void)|undefined = undefined;
// Initialize to an unresolved Promise so we can make sure the element has
// connected before first update.
private _updatePromise =
new Promise((res) => this._enableUpdatingResolver = res);
private _enableUpdatingResolver: (() => void)|undefined;

@@ -501,10 +571,11 @@ /**

connectedCallback() {
this._updateState = this._updateState | STATE_HAS_CONNECTED;
// Ensure first connection completes an update. Updates cannot complete
// before connection and if one is pending connection the
// `_hasConnectionResolver` will exist. If so, resolve it to complete the
// update, otherwise requestUpdate.
if (this._hasConnectedResolver) {
this._hasConnectedResolver();
this._hasConnectedResolver = undefined;
// before connection.
this.enableUpdating();
}
protected enableUpdating() {
if (this._enableUpdatingResolver !== undefined) {
this._enableUpdatingResolver();
this._enableUpdatingResolver = undefined;
}

@@ -567,6 +638,8 @@ }

const ctor = (this.constructor as typeof UpdatingElement);
const propName = ctor._attributeToPropertyMap.get(name);
// Note, hint this as an `AttributeMap` so closure clearly understands
// the type; it has issues with tracking types through statics
// tslint:disable-next-line:no-unnecessary-type-assertion
const propName = (ctor._attributeToPropertyMap as AttributeMap).get(name);
if (propName !== undefined) {
const options =
ctor._classProperties!.get(propName) || defaultPropertyDeclaration;
const options = ctor.getPropertyOptions(propName);
// mark state reflecting

@@ -592,4 +665,3 @@ this._updateState = this._updateState | STATE_IS_REFLECTING_TO_PROPERTY;

const ctor = this.constructor as typeof UpdatingElement;
const options =
ctor._classProperties!.get(name) || defaultPropertyDeclaration;
const options = ctor.getPropertyOptions(name);
if (ctor._valueHasChanged(

@@ -617,3 +689,3 @@ this[name as keyof this], oldValue, options.hasChanged)) {

if (!this._hasRequestedUpdate && shouldRequestUpdate) {
this._enqueueUpdate();
this._updatePromise = this._enqueueUpdate();
}

@@ -644,15 +716,7 @@ }

private async _enqueueUpdate() {
// Mark state updating...
this._updateState = this._updateState | STATE_UPDATE_REQUESTED;
let resolve!: (r: boolean) => void;
let reject!: (e: Error) => void;
const previousUpdatePromise = this._updatePromise;
this._updatePromise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
try {
// Ensure any previous update has resolved before updating.
// This `await` also ensures that property changes are batched.
await previousUpdatePromise;
await this._updatePromise;
} catch (e) {

@@ -662,24 +726,12 @@ // Ignore any previous errors. We only care that the previous cycle is

}
// Make sure the element has connected before updating.
if (!this._hasConnected) {
await new Promise((res) => this._hasConnectedResolver = res);
const result = this.performUpdate();
// If `performUpdate` 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;
}
try {
const result = this.performUpdate();
// If `performUpdate` 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;
}
} catch (e) {
reject(e);
}
resolve(!this._hasRequestedUpdate);
return !this._hasRequestedUpdate;
}
private get _hasConnected() {
return (this._updateState & STATE_HAS_CONNECTED);
}
private get _hasRequestedUpdate() {

@@ -720,2 +772,4 @@ return (this._updateState & STATE_UPDATE_REQUESTED);

this.update(changedProperties);
} else {
this._markUpdated();
}

@@ -726,6 +780,5 @@ } catch (e) {

shouldUpdate = false;
throw e;
} finally {
// Ensure element can accept additional updates after an exception.
this._markUpdated();
throw e;
}

@@ -790,3 +843,3 @@ if (shouldUpdate) {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -803,3 +856,3 @@ protected shouldUpdate(_changedProperties: PropertyValues): boolean {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -815,2 +868,3 @@ protected update(_changedProperties: PropertyValues) {

}
this._markUpdated();
}

@@ -825,3 +879,3 @@

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -838,3 +892,3 @@ protected updated(_changedProperties: PropertyValues) {

*
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/

@@ -841,0 +895,0 @@ protected firstUpdated(_changedProperties: PropertyValues) {

@@ -14,4 +14,3 @@ /**

*/
import {TemplateResult} from 'lit-html';
import {render} from 'lit-html/lib/shady-render.js';
import {render, ShadyRenderOptions} from 'lit-html/lib/shady-render.js';

@@ -36,3 +35,3 @@ import {PropertyValues, UpdatingElement} from './lib/updating-element.js';

(window['litElementVersions'] || (window['litElementVersions'] = []))
.push('2.2.1');
.push('2.3.0-pre.1');

@@ -42,25 +41,8 @@ export interface CSSResultArray extends Array<CSSResult|CSSResultArray> {}

/**
* Minimal implementation of Array.prototype.flat
* @param arr the array to flatten
* @param result the accumlated result
* Sentinal value used to avoid calling lit-html's render function when
* subclasses do not implement `render`
*/
function arrayFlat(
styles: CSSResultArray, result: CSSResult[] = []): CSSResult[] {
for (let i = 0, length = styles.length; i < length; i++) {
const value = styles[i];
if (Array.isArray(value)) {
arrayFlat(value, result);
} else {
result.push(value);
}
}
return result;
}
const renderNotImplemented = {};
/** Deeply flattens styles array. Uses native flat if available. */
const flattenStyles = (styles: CSSResultArray): CSSResult[] =>
styles.flat ? styles.flat(Infinity) : arrayFlat(styles);
export class LitElement extends UpdatingElement {
/**

@@ -74,11 +56,13 @@ * Ensure this class is marked as `finalized` as an optimization ensuring

protected static['finalized'] = true;
/**
* Render method used to render the lit-html TemplateResult to the element's
* DOM.
* @param {TemplateResult} Template to render.
* @param {Element|DocumentFragment} Node into which to render.
* @param {String} Element name.
* Render method used to render the value to the element's DOM.
* @param result The value to render.
* @param container Node into which to render.
* @param options Element name.
* @nocollapse
*/
static render = render;
static render:
(result: unknown, container: Element|DocumentFragment,
options: ShadyRenderOptions) => void = render;

@@ -93,19 +77,20 @@ /**

/** @nocollapse */
protected static finalize() {
// The Closure JS Compiler does not always preserve the correct "this"
// when calling static super methods (b/137460243), so explicitly bind.
super.finalize.call(this);
// Prepare styling that is stamped at first render time. Styling
// is built from user provided `styles` or is inherited from the superclass.
this._styles =
this.hasOwnProperty(JSCompiler_renameProperty('styles', this)) ?
this._getUniqueStyles() :
this._styles || [];
/**
* Return the array of styles to apply to the element.
* Override this method to integrate into a style management system.
*
* @nocollapse
*/
static getStyles(): CSSResult|CSSResultArray|undefined {
return this.styles;
}
/** @nocollapse */
private static _getUniqueStyles(): CSSResult[] {
// Take care not to call `this.styles` multiple times since this generates
// new CSSResults each time.
private static _getUniqueStyles() {
// Only gather styles once per class
if (this.hasOwnProperty(JSCompiler_renameProperty('_styles', this))) {
return;
}
// Take care not to call `this.getStyles()` multiple times since this
// generates new CSSResults each time.
// TODO(sorvell): Since we do not cache CSSResults by input, any

@@ -115,22 +100,28 @@ // shared styles will generate new stylesheet objects, which is wasteful.

// stylesheets.
const userStyles = this.styles;
const styles: CSSResult[] = [];
if (Array.isArray(userStyles)) {
const flatStyles = flattenStyles(userStyles);
// As a performance optimization to avoid duplicated styling that can
// occur especially when composing via subclassing, de-duplicate styles
// preserving the last item in the list. The last item is kept to
// try to preserve cascade order with the assumption that it's most
// important that last added styles override previous styles.
const styleSet = flatStyles.reduceRight((set, s) => {
set.add(s);
// on IE set.add does not return the set.
return set;
}, new Set<CSSResult>());
// Array.from does not work on Set in IE
styleSet.forEach((v) => styles.unshift(v));
} else if (userStyles) {
styles.push(userStyles);
const userStyles = this.getStyles();
if (userStyles === undefined) {
this._styles = [];
} else if (Array.isArray(userStyles)) {
// De-duplicate styles preserving the _last_ instance in the set.
// 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.
const addStyles =
(styles: CSSResultArray, set: Set<CSSResult>): Set<CSSResult> =>
styles.reduceRight(
(set: Set<CSSResult>, s) =>
// Note: On IE set.add() does not return the set
Array.isArray(s) ? addStyles(s, set) : (set.add(s), set),
set);
// Array.from does not work on Set in IE, otherwise return
// Array.from(addStyles(userStyles, new Set<CSSResult>())).reverse()
const set = addStyles(userStyles, new Set<CSSResult>());
const styles: CSSResult[] = [];
set.forEach((v) => styles.unshift(v));
this._styles = styles;
} else {
this._styles = [userStyles];
}
return styles;
}

@@ -153,2 +144,3 @@

super.initialize();
(this.constructor as typeof LitElement)._getUniqueStyles();
(this as {renderRoot: Element | DocumentFragment}).renderRoot =

@@ -220,8 +212,12 @@ this.createRenderRoot();

* this method will *not* trigger another update.
* * @param _changedProperties Map of changed properties with old values
* @param _changedProperties Map of changed properties with old values
*/
protected update(changedProperties: PropertyValues) {
// Setting properties in `render` should not trigger an update. Since
// updates are allowed after super.update, it's important to call `render`
// before that.
const templateResult = this.render();
super.update(changedProperties);
const templateResult = this.render() as unknown;
if (templateResult instanceof TemplateResult) {
// If render is not implemented by the component, don't call lit-html render
if (templateResult !== renderNotImplemented) {
(this.constructor as typeof LitElement)

@@ -247,8 +243,10 @@ .render(

/**
* Invoked on each update to perform rendering tasks. This method must return
* a lit-html TemplateResult. Setting properties inside this method will *not*
* trigger the element to update.
* Invoked on each update to perform rendering tasks. This method may return
* any value renderable by lit-html's NodePart - typically a TemplateResult.
* Setting properties inside this method will *not* trigger the element to
* update.
*/
protected render(): TemplateResult|void {
protected render(): unknown {
return renderNotImplemented;
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc