1
1
'use strict' ;
2
+ const { WeakMap } = require ( '../shared/poorlyfills.js' ) ;
3
+
2
4
// hyperHTML.Component is a very basic class
3
5
// able to create Custom Elements like components
4
6
// including the ability to listen to connect/disconnect
5
7
// events via onconnect/ondisconnect attributes
8
+ // Components can be created imperatively or declaratively.
9
+ // The main difference is that declared components
10
+ // will not automatically render on setState(...)
11
+ // to simplify state handling on render.
6
12
function Component ( ) { }
7
13
Object . defineProperty ( exports , '__esModule' , { value : true } ) . default = Component
8
14
9
15
// components will lazily define html or svg properties
10
16
// as soon as these are invoked within the .render() method
11
17
// Such render() method is not provided by the base class
12
18
// but it must be available through the Component extend.
19
+ // Declared components could implement a
20
+ // render(props) method too and use props as needed.
13
21
function setup ( content ) {
22
+ const children = new WeakMap ;
23
+ const create = Object . create ;
24
+ const createEntry = ( wm , id , component ) => {
25
+ wm . set ( id , component ) ;
26
+ return component ;
27
+ } ;
28
+ const get = ( Class , info , id ) => {
29
+ switch ( typeof id ) {
30
+ case 'object' :
31
+ case 'function' :
32
+ const wm = info . w || ( info . w = new WeakMap ) ;
33
+ return wm . get ( id ) || createEntry ( wm , id , new Class ) ;
34
+ default :
35
+ const sm = info . p || ( info . p = create ( null ) ) ;
36
+ return sm [ id ] || ( sm [ id ] = new Class ) ;
37
+ }
38
+ } ;
39
+ const set = context => {
40
+ const info = { w : null , p : null } ;
41
+ children . set ( context , info ) ;
42
+ return info ;
43
+ } ;
44
+ Object . defineProperties (
45
+ Component ,
46
+ {
47
+ for : {
48
+ configurable : true ,
49
+ value ( context , id ) {
50
+ const info = children . get ( context ) || set ( context ) ;
51
+ return get ( this , info , id == null ? 'default' : id ) ;
52
+ }
53
+ }
54
+ }
55
+ ) ;
14
56
Object . defineProperties (
15
57
Component . prototype ,
16
58
{
@@ -25,11 +67,12 @@ function setup(content) {
25
67
svg : lazyGetter ( 'svg' , content ) ,
26
68
state : lazyGetter ( 'state' , function ( ) { return this . defaultState ; } ) ,
27
69
defaultState : { get ( ) { return { } ; } } ,
28
- setState : { value ( state ) {
70
+ setState : { value ( state , render ) {
29
71
const target = this . state ;
30
72
const source = typeof state === 'function' ? state . call ( this , target ) : state ;
31
73
for ( const key in source ) target [ key ] = source [ key ] ;
32
- this . render ( ) ;
74
+ if ( render !== false ) this . render ( ) ;
75
+ return this ;
33
76
} }
34
77
}
35
78
) ;
0 commit comments