1+ 'use strict' ;
2+
3+ Object . defineProperty ( exports , "__esModule" , {
4+ value : true
5+ } ) ;
6+
7+ var _diffhtml = require ( 'diffhtml' ) ;
8+
9+ const Debounce = new WeakMap ( ) ;
10+ const { setPrototypeOf, freeze, assign, keys } = Object ;
11+
12+ // Convert observed attributes from passed PropTypes.
13+ const getObserved = ( { propTypes } ) => propTypes ? keys ( propTypes ) : [ ] ;
14+
15+ // Creates the `component.props` object.
16+ const createProps = domNode => {
17+ const observedAttributes = getObserved ( domNode . constructor ) ;
18+
19+ return freeze ( observedAttributes . reduce ( ( props , attr ) => assign ( props , {
20+ [ attr ] : attr in domNode ? domNode [ attr ] : domNode . getAttribute ( attr )
21+ } ) , { } ) ) ;
22+ } ;
23+
24+ // Creates the `component.state` object.
25+ const createState = ( domNode , newState ) => {
26+ return freeze ( assign ( { } , domNode . state , newState ) ) ;
27+ } ;
28+
29+ // Facilities a component re-render.
30+ const rerenderComponent = domNode => {
31+ const nextProps = createProps ( domNode ) ;
32+
33+ domNode . props = nextProps ;
34+ ( 0 , _diffhtml . innerHTML ) ( domNode . shadowRoot , domNode . render ( ) ) ;
35+ domNode . componentDidUpdate ( ) ;
36+ } ;
37+
38+ class WebComponent extends HTMLElement {
39+ static get observedAttributes ( ) {
40+ return getObserved ( this ) . map ( key => key . toLowerCase ( ) ) ;
41+ }
42+
43+ constructor ( ) {
44+ super ( ) ;
45+
46+ this . props = createProps ( this ) ;
47+ this . state = createState ( this ) ;
48+ this . componentWillMount ( ) ;
49+ }
50+
51+ setState ( newState ) {
52+ this . state = assign ( { } , this . state , newState ) ;
53+
54+ if ( ! Debounce . has ( this ) && this . shouldComponentUpdate ( ) ) {
55+ rerenderComponent ( this ) ;
56+
57+ Debounce . set ( this , setTimeout ( ( ) => {
58+ Debounce . delete ( this ) ;
59+ rerenderComponent ( this ) ;
60+ } ) ) ;
61+ }
62+ }
63+
64+ connectedCallback ( ) {
65+ this . attachShadow ( { mode : 'open' } ) ;
66+ const nextProps = createProps ( this ) ;
67+ this . componentWillReceiveProps ( nextProps ) ;
68+ rerenderComponent ( this ) ;
69+ this . componentDidMount ( ) ;
70+ }
71+
72+ disconnectedCallback ( ) {
73+ // TODO Figure out a better place for `willUnmount`, use the detached
74+ // transition to determine if a Node is removed would be very accurate
75+ // as this fires just before an element is removed, also if the user
76+ // is using a detached animation this would allow them to do something
77+ // before the animation completes, giving you two nice callbacks to use
78+ // for detaching.
79+ this . componentWillUnmount ( ) ;
80+ this . componentDidUnmount ( ) ;
81+ }
82+
83+ attributeChangedCallback ( ) {
84+ if ( this . shadowRoot && ! Debounce . has ( this ) ) {
85+ const nextProps = createProps ( this ) ;
86+ this . componentWillReceiveProps ( nextProps ) ;
87+ rerenderComponent ( this ) ;
88+
89+ Debounce . set ( this , setTimeout ( ( ) => {
90+ Debounce . delete ( this ) ;
91+ rerenderComponent ( this ) ;
92+ } ) ) ;
93+ }
94+ }
95+
96+ shouldComponentUpdate ( ) {
97+ return true ;
98+ }
99+ componentWillReceiveProps ( ) { }
100+ componentWillMount ( ) { }
101+ componentDidMount ( ) { }
102+ componentDidUpdate ( ) { }
103+ componentWillUnmount ( ) { }
104+ componentDidUnmount ( ) { }
105+ } exports . default = WebComponent ;
106+ ;
107+ module . exports = exports [ 'default' ] ;
0 commit comments