11/*globals CustomEvent, config*/
2- import { getAttributes , getValueFromObject , dotNotationToObject } from "@cocreate/utils" ;
3- import observer from "@cocreate/observer" ;
4- import socket from "@cocreate/socket-client" ;
5- import action from '@cocreate/actions' ;
2+ import { getValueFromObject , dotNotationToObject } from "@cocreate/utils" ;
3+ import Observer from "@cocreate/observer" ;
4+ import Socket from "@cocreate/socket-client" ;
5+ import Actions from '@cocreate/actions' ;
66import { render } from '@cocreate/render' ;
77import '@cocreate/element-prototype' ;
88
99const CoCreateApi = {
10- components : { } ,
11-
12- init : function ( { name, endPoints, options } ) {
13- this . register ( { name, endPoints, options } ) ;
14- if ( options && options . socket !== false && ! socket . sockets . size )
15- socket . create ( { prefix : 'api' } ) ;
10+ modules : { } ,
11+
12+ init : function ( moduleConfig ) {
13+ if ( ! moduleConfig ) {
14+ let elements = document . querySelectorAll ( '[api], [module]' )
15+ for ( let i = 0 ; i < elements . length ; i ++ ) {
16+ let name = elements [ i ] . getAttribute ( 'api' ) || elements [ i ] . getAttribute ( 'module' )
17+ this . register ( { name, endPoints : { } } ) ;
18+ }
19+ } else {
20+ let { name, endPoints, options } = moduleConfig
21+ this . register ( { name, endPoints, options } ) ;
22+ if ( options && options . socket !== false && ! Socket . sockets . size )
23+ Socket . create ( { prefix : 'api' } ) ;
24+ }
1625 } ,
1726
1827 register : function ( { name, endPoints, options } ) {
1928 const self = this ;
20- if ( typeof this . components [ name ] === 'undefined' ) {
21- this . components [ name ] = { name, endPoints, options } ;
29+ if ( typeof this . modules [ name ] === 'undefined' ) {
30+ this . modules [ name ] = { name, endPoints, options } ;
2231
23- socket . listen ( name , ( data ) => {
24- self . __response ( name , data ) ;
32+ Socket . listen ( name , ( data ) => {
33+ self . response ( name , data ) ;
2534 } ) ;
2635
27- for ( const endPoint of Object . keys ( endPoints ) ) {
28- socket . listen ( name + '.' + endPoint , ( data ) => {
29- self . __response ( name , data ) ;
30- } ) ;
31-
32- let functions = endPoints [ endPoint ]
33- if ( typeof functions . request !== 'function' ) {
34- functions . request = self . __request ;
36+ Actions . init ( {
37+ name,
38+ callback : ( action ) => {
39+ action . form = action . form || document
40+ self . request ( { ...action , type : 'action' } )
3541 }
36- action . init ( {
37- name : endPoint ,
38- endEvent : endPoint ,
39- callback : ( data ) => {
40- const element = data . element
41- let form = data . form || document
42- const selector = `[${ name } ^="${ endPoint } ."]`
43- let el = form . querySelector ( selector )
44- if ( ! el ) return
45- let params = self . parseParams ( { name, element : el } )
46- if ( params ) {
47- functions . request ( { name, ...params , element, form, type : 'action' } )
48- }
49- } ,
50- } ) ;
51- }
42+ } ) ;
5243
5344 const inputEvent = ( element ) => {
54- const self = this
5545 element . addEventListener ( 'input' , ( e ) => {
56- if ( element . hasAttribute ( name ) ) {
57- let params = self . parseParams ( { name, element } )
58- if ( params ) {
59- if ( ! e . detail || e . detail && e . detail . skip != true ) {
60- endPoints [ params . endPoint ] . request ( { name, ...params , element, type : 'input' } )
61- }
62- }
46+ if ( ! e . detail || e . detail && e . detail . skip != true ) {
47+ self . request ( { name, element, type : 'input' } )
6348 }
6449 } ) ;
6550 }
6651
6752 let elements = document . querySelectorAll ( `[${ name } ]` )
68- for ( let element of elements ) {
69- let params = this . parseParams ( { name, element } )
70- if ( params ) {
71- endPoints [ params . endPoint ] . request ( { name, ...params , element, type : 'onload' } )
72- inputEvent ( element )
73- }
53+ for ( let i = 0 ; i < elements . length ; i ++ ) {
54+ inputEvent ( elements [ i ] )
55+ this . request ( { name, element : elements [ i ] , type : 'onload' } )
7456 }
7557
76- observer . init ( {
58+ Observer . init ( {
7759 name : `${ name } NodeObserver` ,
7860 observe : [ 'addedNodes' ] ,
7961 target : `[${ name } ]` ,
8062 callback : function ( mutation ) {
81- let params = self . parseParams ( { name, element : mutation . target } )
82- if ( params ) {
83- endPoints [ params . endPoint ] . request ( { name, ...params , element : mutation . target , type : 'nodeObserver' } ) ;
84- inputEvent ( mutation . target )
85- }
63+ inputEvent ( mutation . target )
64+ self . request ( { name, element : mutation . target , type : 'nodeObserver' } )
8665 }
8766 } ) ;
8867
89- observer . init ( {
68+ Observer . init ( {
9069 name : `${ name } AttributeObserver` ,
9170 observe : [ 'attributes' ] ,
9271 attributeName : [ name ] ,
9372 callback : function ( mutation ) {
94- let params = self . parseParams ( { name, element : mutation . target } )
95- if ( params ) {
96- endPoints [ params . endPoint ] . request ( { name, ...params , element : mutation . target , type : 'attributeObserver' } ) ;
97- }
73+ self . request ( { name, element : mutation . target , type : 'attributeObserver' } )
9874 }
9975 } ) ;
10076 }
10177 } ,
10278
10379
104- __request : async function ( object ) {
105- if ( object . type !== 'action' )
106- return
107- if ( ! object . form )
108- object . form = element . closest ( 'form' ) ;
109- let data = await CoCreateApi . getData ( object ) ;
110- CoCreateApi . send ( object . name , object . endPoint , data ) ;
111- } ,
112-
113- __response : function ( name , data ) {
114- const endPoint = data . method . substring ( name . length + 1 ) ;
115- const component = this . components [ name ] ;
116- const functions = component . endPoints [ endPoint ]
117- if ( functions . listen !== false ) {
118- if ( typeof functions . response === 'function' ) {
119- functions . response ( data [ name ] ) ;
120- } else if ( data . error ) {
121- render ( {
122- selector : `[template*='${ name } ']` ,
123- data : [ {
124- type : name ,
125- status : 'failed' ,
126- message : data . error
127- } ]
128- } ) ;
129- } else {
130- CoCreateApi . setData ( { name, endPoint, data } )
131-
132- document . dispatchEvent ( new CustomEvent ( endPoint , {
133- detail : {
134- data : data [ name ]
135- }
136- } ) ) ;
137- }
80+ request : async function ( object ) {
81+ if ( object . element ) {
82+ if ( ! object . method )
83+ object . method = object . element . getAttribute ( object . name )
84+ if ( ! object . key )
85+ object . key = object . element . getAttribute ( `${ object . name } -key` )
86+ if ( ! object . event )
87+ object . event = object . element . getAttribute ( `${ object . name } -event` )
13888 }
139- } ,
14089
141- send : function ( name , endPoint , data ) {
142- let method = name + '.' + endPoint
143- socket . send ( { method, endPoint, [ name ] : data , broadcastBrowser : false , status : 'await' } ) ;
90+ if ( this . modules [ object . name ] [ object . method ] && this . modules [ object . name ] [ object . method ] . request )
91+ this . modules [ object . name ] [ object . method ] . request ( object )
92+ else if ( ! object . event && object . type === 'action' || object . event && object . event . includes ( object . type ) ) {
93+ let data = await CoCreateApi . getData ( object ) ;
94+ CoCreateApi . send ( object . name , object . method , data ) ;
95+ }
14496 } ,
14597
146- parseParams : function ( { name, endPoint, element } ) {
147- let attribute = element . getAttribute ( name )
148- if ( ! attribute )
149- return false
98+ response : function ( name , data ) {
99+ const method = data . method . substring ( name . length + 1 ) ;
100+ if ( this . modules [ name ] [ method ] && this . modules [ name ] [ method ] . response )
101+ this . modules [ name ] [ method ] . response ( data [ name ] )
102+ else if ( data . error ) {
103+ render ( {
104+ selector : `[template*='${ name } ']` ,
105+ data : [ {
106+ type : name ,
107+ method,
108+ status : 'failed' ,
109+ message : data . error
110+ } ]
111+ } ) ;
112+ } else {
113+ CoCreateApi . setData ( { name, method, data } )
150114
151- let endPoints = this . components [ name ] . endPoints
152- for ( let k of Object . keys ( endPoints ) ) {
153- if ( attribute . startsWith ( k ) ) {
154- endPoint = k
155- break ;
156- }
115+ document . dispatchEvent ( new CustomEvent ( name , {
116+ detail : {
117+ data : data [ name ]
118+ }
119+ } ) ) ;
157120 }
158-
159- let key = attribute . substring ( endPoint . length + 1 ) ;
160- return { endPoint, key, dotNotation : attribute }
161-
162121 } ,
163122
123+ send : function ( name , method , data ) {
124+ Socket . send ( { method : name + '.' + method , [ name ] : data , broadcastBrowser : false , status : 'await' } ) ;
125+ } ,
164126
165- getData : async function ( { name, endPoint, element, form } ) {
127+ // TODO: handle $param operator
128+ getData : async function ( { name, method, element, form } ) {
166129 const data = { }
167- const selector = `[${ name } ^="${ endPoint } ."]`
130+
131+ if ( ! form && element )
132+ form = element . closest ( 'form' ) ;
133+
168134 let elements
169135 if ( form )
170- elements = form . querySelectorAll ( selector ) ;
136+ elements = form . querySelectorAll ( `[ ${ name } =" ${ method } "]` ) ;
171137 if ( ! elements || elements . length == 0 )
172138 elements = [ element ]
173- for ( let el of elements ) {
174- if ( ! el || el . closest ( '[template]' ) ) continue
175- let params = this . parseParams ( { name, element : el } )
176- if ( params . key ) {
177- data [ params . key ] = await el . getValue ( )
139+
140+ for ( let i = 0 ; i < elements . length ; i ++ ) {
141+ if ( ! elements [ i ] || elements [ i ] . closest ( '[template]' ) )
142+ continue
143+ let key = elements [ i ] . getAttribute ( `${ name } -key` )
144+ if ( key ) {
145+ data [ key ] = await elements [ i ] . getValue ( )
178146 }
179147 }
180148
181149 return dotNotationToObject ( data ) ;
182150 } ,
183151
184- setData : function ( { name , endPoint , data , form } ) {
185- const selector = `[ ${ name } ^=" ${ endPoint } ."]`
152+ // TODO: handle $param operator
153+ setData : function ( { name , method , data , form } ) {
186154 if ( ! form )
187155 form = document ;
188- let elements = form . querySelectorAll ( selector ) ;
189- if ( ! elements || elements . length == 0 ) return
190156
191- for ( let el of elements ) {
192- let attribute = el . getAttribute ( name )
157+ let elements = form . querySelectorAll ( `[${ name } ="${ method } "]` ) ;
158+ if ( ! elements || elements . length == 0 )
159+ return
160+
161+ for ( let i = 0 ; i < elements . length ; i ++ ) {
162+ let attribute = elements [ i ] . getAttribute ( name )
193163 if ( attribute ) {
194- if ( el . hasAttribute ( 'actions' ) ) continue ;
195- let templateid = el . getAttribute ( 'template_id' )
164+ if ( elements [ i ] . hasAttribute ( 'actions' ) ) continue ;
165+ let templateid = elements [ i ] . getAttribute ( 'template_id' )
196166 if ( templateid ) {
197167 let items = document . querySelectorAll ( `[templateid="${ templateid } "]` )
198168 for ( let item of items )
@@ -202,8 +172,9 @@ const CoCreateApi = {
202172 data
203173 } ) ;
204174 } else {
205- let value = getValueFromObject ( data , attribute ) ;
206- el . setValue ( value ) ;
175+ let key = elements [ i ] . getAttribute ( `${ name } -key` )
176+ let value = getValueFromObject ( data [ name ] , key ) ;
177+ elements [ i ] . setValue ( value ) ;
207178 }
208179 }
209180 }
@@ -212,4 +183,16 @@ const CoCreateApi = {
212183
213184} ;
214185
186+ Observer . init ( {
187+ name : `apiNodeObserver` ,
188+ observe : [ 'addedNodes' ] ,
189+ target : '[module], [api]' ,
190+ callback : function ( mutation ) {
191+ let name = mutation . target . getAttribute ( 'api' ) || mutation . target . getAttribute ( 'module' )
192+ CoCreateApi . register ( { name, endPoints : { } } ) ;
193+ }
194+ } ) ;
195+
196+ CoCreateApi . init ( )
197+
215198export default CoCreateApi ;
0 commit comments