11import { _$toArgs , _$List } from './list' ;
2- import { _$el , _$getAttr , _$setAttr , _$select , _$assignEl } from './dom' ;
2+ import { _$el , _$getAttr , _$setAttr , _$select , _$assignEl , _$removeEl } from './dom' ;
33
44function _$toLowerCase ( str : string ) {
55 return str . toLowerCase ( ) ;
@@ -19,6 +19,9 @@ export const _$assign = Object['assign'] || function (t: Object) {
1919 }
2020 return t ;
2121} ;
22+ export function _$apply ( callee : Function , args : any [ ] , globs : any [ ] , thisArg : any = null ) {
23+ return callee . apply ( thisArg , args . concat ( globs ) ) ;
24+ }
2225export function _$isValueAttr ( attr : string ) {
2326 return attr === 'value' ;
2427}
@@ -38,10 +41,7 @@ export function _$dispatch(root: Component, key: string, oldVal, value) {
3841 }
3942 root . $update ( ) ;
4043}
41- export function _$extend ( ctor : Function , exts : Function ) {
42- ctor [ 'plugin' ] = function ( fn : PluginFn , options ?: ObjectLike < any > ) {
43- TPS . push ( { options, fn } ) ;
44- } ;
44+ export function _$extends ( ctor : Function , exts : Function ) {
4545 ctor [ PROP_MAP . h ] = Object . create ( exts [ PROP_MAP . h ] ) ;
4646 ctor [ PROP_MAP . h ] . constructor = ctor ;
4747}
@@ -135,13 +135,16 @@ export function _$toPlainObject(obj: Component) {
135135 } ) ;
136136 return _$isObject ( obj ) ? data : obj ;
137137}
138- export function _$setReference ( obj : Object , prop : string ) {
139- const value = [ ] ;
140- _$define ( obj , prop , {
141- get : ( ) => value . length <= 1 ? value [ 0 ] : value ,
142- set : val => { val && ! ~ value . indexOf ( val ) && value . push ( val ) ; } ,
143- enumerable : true , configurable : true
144- } ) ;
138+ export function _$setReference ( refs : Object , prop : string , node : HTMLElement ) {
139+ if ( ! _$hasProp ( refs , prop ) ) {
140+ const value = [ ] ;
141+ _$define ( refs , prop , {
142+ get : ( ) => value . length <= 1 ? value [ 0 ] : value ,
143+ set : val => { val && ! ~ value . indexOf ( val ) && value . push ( val ) ; } ,
144+ enumerable : true , configurable : true
145+ } ) ;
146+ }
147+ refs [ prop ] = node ;
145148}
146149export function _$accesor ( object : Component , path : string , value ?: any ) {
147150 return path . split ( '.' ) . reduce ( ( obj , key , i , arr ) => {
@@ -198,41 +201,78 @@ export function _$bindStyle(value: string | ObjectLike<any>) {
198201 return '' ;
199202 }
200203}
201- export function _$conditionalUpdate ( block : { type : string } & ComponentTemplate , condition : Function , inst : Component , parent : Element , anchor : Element ) {
202- if ( block && block . type === condition ( inst ) . type ) {
203- block . $update ( inst ) ;
204+ export function _$conditionalUpdate ( block : { type : string } & ComponentTemplate , condition : Function , parent : Element , anchor : Element , inst : Component ) {
205+ let globs = _$toArgs ( arguments , 5 ) ;
206+ if ( block && block . type === _$apply ( condition , [ inst ] , globs ) . type ) {
207+ _$apply ( block . $update , [ inst ] , globs , block ) ;
204208 } else {
205209 block && block . $destroy ( ) ;
206- block = condition ( inst ) ;
210+ block = _$apply ( condition , [ inst ] , globs ) ;
207211 block . $create ( ) ;
208- block . $mount ( parent , anchor ) ;
212+ block . $mount ( parent || inst . $parentEl , anchor ) ;
209213 }
210214 return block ;
211215}
212216export function _$bindUpdate ( el : ( HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement ) & { _value : any } , binding : [ string , any ] ) {
213217 let [ attr , value ] = binding ;
214- let _value : string | boolean = attr === 'checked' ? ! ! value : _$toString ( value ) ;
215- if ( / v a l u e | c h e c k e d / . test ( attr ) ) {
216- if ( el [ attr ] !== _value ) el [ attr ] = _$isValueAttr ( attr ) ? _value : value ;
217- el [ PROP_MAP . _ ] = _$isValueAttr ( attr ) ? value : el [ PROP_MAP . v ] ;
218+ let _value : string = _$toString ( value ) ;
219+ if ( _$isValueAttr ( attr ) ) {
220+ if ( el [ attr ] !== _value ) el [ attr ] = _value ;
221+ el [ PROP_MAP . _ ] = value ;
218222 } else if ( _$getAttr ( el , attr ) !== _value ) {
219223 _$setAttr ( el , [ attr , _value ] ) ;
220224 }
221225}
222- export function _$bindBooleanAttr ( el : Element , attrAndValue : [ string , any ] ) {
223- let [ attr , value , hasAttr ] = attrAndValue . concat ( [ el . hasAttribute ( attrAndValue [ 0 ] ) ] ) ;
224- value == null || value === false ? hasAttr && el . removeAttribute ( attr ) : _$setAttr ( el , [ attr , '' ] ) ;
226+ export function _$bindBooleanAttr ( el : HTMLElement , attrAndValue : [ string , any ] ) {
227+ let [ attr , value ] = attrAndValue ;
228+ el [ attr ] = value == null || value === false ? ( el . removeAttribute ( attr ) , false ) : ( _$setAttr ( el , [ attr , '' ] ) , true ) ;
225229}
226230export function _$textUpdate ( text : Text , value : string ) {
227231 if ( text . data !== ( value = _$toString ( value ) ) ) text . data = value ;
228232}
229233export function _$tagUpdate < T extends keyof HTMLElementTagNameMap > ( node : HTMLElement , tag : T ) {
230234 return _$toLowerCase ( tag ) !== _$toLowerCase ( node . tagName ) ? _$assignEl ( node , _$el ( tag ) ) : node ;
231235}
236+ export function _$removeReference ( refs : Object , prop : string , node : HTMLElement ) {
237+ let nodes = refs [ prop ] ;
238+ _$isArray ( nodes ) ? refs [ prop ] . splice ( nodes . indexOf ( node ) , 1 ) : ( delete refs [ prop ] ) ;
239+ }
240+ export function _$htmlUpdate ( node : HTMLElement , value : string ) {
241+ if ( node . innerHTML !== ( value = _$toString ( value ) ) ) node . innerHTML = value ;
242+ }
243+ export function _$componentUpdate ( parent : Component , Ctor : ComponentConstructor , inst : Component , value : ComponentConstructor , attrs : AttrParams , el : HTMLElement , sibling : HTMLElement ) {
244+ if ( value === Ctor ) {
245+ inst && inst . $update ( ) ;
246+ } else {
247+ Ctor = value ;
248+ if ( inst ) {
249+ inst . $destroy ( ) ;
250+ _$removeChild ( parent , inst ) ;
251+ }
252+ if ( inst ) {
253+ inst = _$addChild ( parent , Ctor , attrs ) ;
254+ inst . $create ( ) ;
255+ inst . $mount ( el , sibling ) ;
256+ }
257+ }
258+ return [ inst , Ctor ] ;
259+ }
260+ export function _$destroyComponent ( component : Component ) {
261+ component . $unmount ( ) ;
262+ component . $parent = null ;
263+ component . $parentEl = null ;
264+ component . $siblingEl = null ;
265+ component . $children . splice ( 0 , component . $children . length ) ;
266+ }
267+ export function _$setElements ( component : Component , parent : HTMLElement , sibling ?: HTMLElement ) {
268+ let brother = _$select ( sibling ) ;
269+ component . $siblingEl = brother ;
270+ component . $parentEl = sibling && brother . parentElement || _$select ( parent ) ;
271+ }
232272export function _$forLoop ( root : Component , obj : any [ ] , loop : ( ...args : any [ ] ) => ComponentTemplate ) {
233273 let items : ObjectLike < ComponentTemplate > = { } , loopParent : Element , loopSibling : Element ;
234274 let globs = _$toArgs ( arguments , 3 ) ;
235- _$each ( obj , ( item , i ) => { items [ i ] = loop . apply ( null , [ root , item , i ] . concat ( globs ) ) ; } ) ;
275+ _$each ( obj , ( item , i , index ) => { items [ i ] = _$ apply( loop , [ root , item , i , index ] , globs ) ; } ) ;
236276 return {
237277 $create ( ) {
238278 _$each ( items , item => { item . $create ( ) ; } ) ;
@@ -244,17 +284,17 @@ export function _$forLoop(root: Component, obj: any[], loop: (...args: any[]) =>
244284 } ,
245285 $update ( root : Component , obj : any [ ] ) {
246286 let globs = _$toArgs ( arguments , 2 ) ;
247- _$each ( items , ( item , i ) => {
287+ _$each ( items , ( item , i , index ) => {
248288 if ( obj [ i ] ) {
249- item . $update . apply ( item , [ root , obj [ i ] , i ] . concat ( globs ) ) ;
289+ _$ apply( item . $update , [ root , obj [ i ] , i , index ] , globs , item ) ;
250290 } else {
251291 item . $destroy ( ) ;
252292 delete items [ i ] ;
253293 }
254294 } ) ;
255- _$each ( obj , ( item , i ) => {
295+ _$each ( obj , ( item , i , index ) => {
256296 if ( ! items [ i ] ) {
257- items [ i ] = loop . apply ( null , [ root , item , i ] . concat ( globs ) ) ;
297+ items [ i ] = _$ apply( loop , [ root , item , i , index ] , globs ) ;
258298 items [ i ] . $create ( ) ;
259299 items [ i ] . $mount ( loopParent , loopSibling ) ;
260300 }
@@ -265,10 +305,11 @@ export function _$forLoop(root: Component, obj: any[], loop: (...args: any[]) =>
265305 }
266306 } ;
267307}
268- export function _$each < T > ( obj : T , cb : ( value : IterateValue < T > , key : IterateKey < T > ) => void ) {
308+ export function _$each < T > ( obj : T , cb : ( value : IterateValue < T > , key : IterateKey < T > , index ?: number ) => void ) {
309+ let i = 0 ;
269310 for ( const key in obj ) {
270311 if ( _$hasProp ( obj , key ) ) {
271- cb ( < any > obj [ key ] , < any > ( isNaN ( + key ) ? key : + key ) ) ;
312+ cb ( < any > obj [ key ] , < any > ( isNaN ( + key ) ? key : + key ) , i ++ ) ;
272313 }
273314 }
274315}
0 commit comments