UNPKG

es5-lit-element

Version:
228 lines (206 loc) 7.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.property = property; exports.query = query; exports.queryAll = queryAll; exports.eventOptions = exports.customElement = void 0; /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ var legacyCustomElement = function legacyCustomElement(tagName, clazz) { window.customElements.define(tagName, clazz); // Cast as any because TS doesn't recognize the return type as being a // subtype of the decorated class when clazz is typed as // `Constructor<HTMLElement>` for some reason. // `Constructor<HTMLElement>` is helpful to make sure the decorator is // applied to elements however. // tslint:disable-next-line:no-any return clazz; }; var standardCustomElement = function standardCustomElement(tagName, descriptor) { var kind = descriptor.kind, elements = descriptor.elements; return { kind: kind, elements: elements, // This callback is called once the class is otherwise fully defined finisher: function finisher(clazz) { window.customElements.define(tagName, clazz); } }; }; /** * Class decorator factory that defines the decorated class as a custom element. * * @param tagName the name of the custom element to define */ var customElement = function customElement(tagName) { return function (classOrDescriptor) { return typeof classOrDescriptor === 'function' ? legacyCustomElement(tagName, classOrDescriptor) : standardCustomElement(tagName, classOrDescriptor); }; }; exports.customElement = customElement; var standardProperty = function standardProperty(options, element) { // When decorating an accessor, pass it through and add property metadata. // Note, the `hasOwnProperty` check in `createProperty` ensures we don't // stomp over the user's accessor. if (element.kind === 'method' && element.descriptor && !('value' in element.descriptor)) { return Object.assign({}, element, { finisher: function finisher(clazz) { clazz.createProperty(element.key, options); } }); } else { // createProperty() takes care of defining the property, but we still // must return some kind of descriptor, so return a descriptor for an // unused prototype field. The finisher calls createProperty(). return { kind: 'field', key: Symbol(), placement: 'own', descriptor: {}, // When @babel/plugin-proposal-decorators implements initializers, // do this instead of the initializer below. See: // https://github.com/babel/babel/issues/9260 extras: [ // { // kind: 'initializer', // placement: 'own', // initializer: descriptor.initializer, // } // ], initializer: function initializer() { if (typeof element.initializer === 'function') { this[element.key] = element.initializer.call(this); } }, finisher: function finisher(clazz) { clazz.createProperty(element.key, options); } }; } }; var legacyProperty = function legacyProperty(options, proto, name) { proto.constructor.createProperty(name, options); }; /** * A property decorator which creates a LitElement property which reflects a * corresponding attribute value. A `PropertyDeclaration` may optionally be * supplied to configure property features. * * @ExportDecoratedItems */ function property(options) { // tslint:disable-next-line:no-any decorator return function (protoOrDescriptor, name) { return name !== undefined ? legacyProperty(options, protoOrDescriptor, name) : standardProperty(options, protoOrDescriptor); }; } /** * A property decorator that converts a class property into a getter that * executes a querySelector on the element's renderRoot. * * @ExportDecoratedItems */ function query(selector) { return function (protoOrDescriptor, // tslint:disable-next-line:no-any decorator name) { var descriptor = { get: function get() { 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 */ function queryAll(selector) { return function (protoOrDescriptor, // tslint:disable-next-line:no-any decorator name) { var descriptor = { get: function get() { return this.renderRoot.querySelectorAll(selector); }, enumerable: true, configurable: true }; return name !== undefined ? legacyQuery(descriptor, protoOrDescriptor, name) : standardQuery(descriptor, protoOrDescriptor); }; } var legacyQuery = function legacyQuery(descriptor, proto, name) { Object.defineProperty(proto, name, descriptor); }; var standardQuery = function standardQuery(descriptor, element) { return { kind: 'method', placement: 'prototype', key: element.key, descriptor: descriptor }; }; var standardEventOptions = function standardEventOptions(options, element) { return Object.assign({}, element, { finisher: function finisher(clazz) { Object.assign(clazz.prototype[element.key], options); } }); }; var legacyEventOptions = // tslint:disable-next-line:no-any legacy decorator function legacyEventOptions(options, proto, name) { Object.assign(proto[name], options); }; /** * Adds event listener options to a method used as an event listener in a * lit-html template. * * @param options An object that specifis event listener options as accepted by * `EventTarget#addEventListener` and `EventTarget#removeEventListener`. * * Current browsers support the `capture`, `passive`, and `once` options. See: * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters * * @example * * class MyElement { * * clicked = false; * * render() { * return html`<div @click=${this._onClick}`><button></button></div>`; * } * * @eventOptions({capture: true}) * _onClick(e) { * this.clicked = true; * } * } */ var eventOptions = function eventOptions(options) { return (// 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 function (protoOrDescriptor, name) { return name !== undefined ? legacyEventOptions(options, protoOrDescriptor, name) : standardEventOptions(options, protoOrDescriptor); } ); }; exports.eventOptions = eventOptions;