license /**
 * This is a modified version of Angular Elements `createCustomElement` that
 * can be initialized with just `observedAttributes` instead of an actual
 * ComponentType. This lets the custom element be a shell for the actual
 * Ivy element that can be loaded at a later time.
 */ import { Injector , ɵComponentType as ComponentType } from '@angular/core' ; import { NgElementStrategy , NgElementStrategyFactory } from './element-strategy' ; import { createCustomEvent , getComponentInputs , getDefaultAttributeToPropertyInputs } from './utils' ; import { Subscription } from 'rxjs' ; /**
 * Prototype for a class constructor based on an Angular component
 * that can be used for custom element registration. Implemented and returned
 * by the  createCustomElement .
 *
 *  publicApi export interface NgElementConstructor < P > { /**
     * An array of observed attribute names for the custom element,
     * derived by transforming input property names from the source component.
     */ readonly observedAttributes : string [ ] ; param injector new ( injector ) : NgElement & WithProperties < P > ; } publicApi export abstract class NgElement extends HTMLElement { /**
     * The strategy that controls how a component is transformed in a custom element.
     */ protected ngElementStrategy ! : NgElementStrategy ; /**
     * A subscription to change, connect, and disconnect events in the custom element.
     */ protected ngElementEventsSubscription : Subscription | null = null ; param attrName param oldValue param newValue param namespace returns abstract attributeChangedCallback ( attrName , oldValue , newValue , namespace ? ) ; returns abstract connectedCallback ( ) ; returns abstract disconnectedCallback ( ) ; } publicApi export type WithProperties < P > = { [ property in keyof P ] : P [ property ] ; } ; publicApi export interface NgElementConfig { /**
     * An optional custom strategy factory to use instead of the default.
     * The strategy controls how the transformation is performed.
     */ strategyFactory : NgElementStrategyFactory ; } description param component param config returns publicApi export function createCustomElement < P > ( component , config ) { const inputs = getComponentInputs ( component ) ; const strategyFactory = config . strategyFactory ; const attributeToPropertyInputs = getDefaultAttributeToPropertyInputs ( inputs ) ; class NgElementImpl extends NgElement { static readonly [ 'observedAttributes' ] = [ '_boot' ] . concat ( Object . keys ( attributeToPropertyInputs ) ) ; constructor ( ) { super ( ) ; this . ngElementStrategy = strategyFactory . create ( ) ; } attributeChangedCallback ( attrName , oldValue , newValue , namespace ? ) { if ( ! this . ngElementStrategy ) { this . ngElementStrategy = strategyFactory . create ( ) ; } const propName = attributeToPropertyInputs [ attrName ] || attrName ; this . ngElementStrategy . setInputValue ( propName , newValue , true ) ; } connectedCallback ( ) { if ( ! this . ngElementStrategy ) { this . ngElementStrategy = strategyFactory . create ( ) ; } this . ngElementStrategy . connect ( this , this . upgradedCallback . bind ( this ) ) ; } upgradedCallback ( ) { const callback = ( name ) => { return value => { const customEvent = createCustomEvent ( this . ownerDocument ! , name , value ) ; this . dispatchEvent ( customEvent ) ; } ; } ; if ( this . ngElementStrategy . events . length > 0 ) { this . ngElementEventsSubscription = this . ngElementStrategy . events [ 0 ] . output . subscribe ( callback ( this . ngElementStrategy . events [ 0 ] . templateName ) ) ; for ( let i = 1 ; i < this . ngElementStrategy . events . length ; i ++ ) { this . ngElementEventsSubscription . add ( this . ngElementStrategy . events [ i ] . output . subscribe ( callback ( this . ngElementStrategy . events [ i ] . templateName ) ) ) ; } } } disconnectedCallback ( ) { if ( this . ngElementStrategy ) { this . ngElementStrategy . disconnect ( ) ; } if ( this . ngElementEventsSubscription != null ) { this . ngElementEventsSubscription . unsubscribe ( ) ; } } } inputs . map ( ( { propName } ) => propName ) . forEach ( property => { Object . defineProperty ( NgElementImpl . prototype , property , { get : function ( ) { return this . ngElementStrategy . getInputValue ( property ) ; } , set : function ( newValue ) { this . ngElementStrategy . setInputValue ( property , newValue , false ) ; } , configurable : true , enumerable : true , } ) ; } ) ; return ( NgElementImpl as any ) as NgElementConstructor < P > ; }