2017-01-02 02:22:45 -08:00
/ * *
* Copyright ( c ) 2014 - present , Facebook , Inc .
* All rights reserved .
*
* This source code is licensed under the BSD - style license found in the
* LICENSE file in the root directory of this source tree . An additional grant
* of patent rights can be found in the PATENTS file in the same directory .
* /
function patch ( prototype , name , fn ) {
let original = prototype [ name ] ;
prototype [ name ] = function ( ... args ) {
return fn . call ( this , original , ... args ) ;
} ;
}
module . exports = function ( bind , lib ) {
2017-01-04 04:33:39 -08:00
let constants = Object . assign ( {
UNDEFINED : NaN
} , require ( ` ./YGEnums ` ) ) ;
2017-01-02 02:22:45 -08:00
class Layout {
constructor ( left , right , top , bottom , width , height ) {
this . left = left ;
this . right = right ;
this . top = top ;
this . bottom = bottom ;
this . width = width ;
this . height = height ;
}
fromJS ( expose ) {
expose ( this . left , this . right , this . top , this . bottom , this . width , this . height ) ;
}
toString ( ) {
return ` <Layout# ${ this . left } : ${ this . right } ; ${ this . top } : ${ this . bottom } ; ${ this . width } : ${ this . height } > ` ;
}
}
class Size {
static fromJS ( { width , height } ) {
return new Size ( width , height ) ;
}
constructor ( width , height ) {
this . width = width ;
this . height = height ;
}
fromJS ( expose ) {
expose ( this . width , this . height ) ;
}
toString ( ) {
return ` <Size# ${ this . width } x ${ this . height } > ` ;
}
}
2017-01-04 04:33:39 -08:00
class Value {
constructor ( unit , value ) {
this . unit = unit ;
this . value = value ;
}
fromJS ( expose ) {
expose ( this . unit , this . value ) ;
}
toString ( ) {
switch ( this . unit ) {
2017-02-14 14:26:13 -08:00
case constants . UNIT _POINT :
2017-01-04 04:33:39 -08:00
return ` ${ this . value } ` ;
case constants . UNIT _PERCENT :
return ` ${ this . value } % ` ;
2017-02-20 05:31:20 -08:00
2017-02-14 14:26:09 -08:00
case constants . UNIT _AUTO :
return ` auto ` ;
2017-01-04 04:33:39 -08:00
default : {
return ` ${ this . value } ? ` ;
}
}
}
valueOf ( ) {
return this . value ;
}
}
for ( let fnName of [ ` setPosition ` , ` setMargin ` , ` setFlexBasis ` , ` setWidth ` , ` setHeight ` , ` setMinWidth ` , ` setMinHeight ` , ` setMaxWidth ` , ` setMaxHeight ` , ` setPadding ` ] ) {
2017-02-20 05:31:20 -08:00
let methods = { [ constants . UNIT _POINT ] : lib . Node . prototype [ fnName ] , [ constants . UNIT _PERCENT ] : lib . Node . prototype [ ` ${ fnName } Percent ` ] , [ constants . UNIT _AUTO ] : lib . Node . prototype [ ` ${ fnName } Auto ` ] } ;
2017-01-04 04:33:39 -08:00
patch ( lib . Node . prototype , fnName , function ( original , ... args ) {
// We patch all these functions to add support for the following calls:
2017-02-20 05:31:20 -08:00
// .setWidth(100) / .setWidth("100%") / .setWidth(.getWidth()) / .setWidth("auto")
2017-01-04 04:33:39 -08:00
let value = args . pop ( ) ;
let unit , asNumber ;
2017-02-20 05:31:20 -08:00
if ( value === ` auto ` ) {
unit = constants . UNIT _AUTO ;
asNumber = undefined ;
} else if ( value instanceof Value ) {
2017-01-04 04:33:39 -08:00
unit = value . unit ;
asNumber = value . valueOf ( ) ;
} else {
2017-02-14 14:26:13 -08:00
unit = typeof value === ` string ` && value . endsWith ( ` % ` ) ? constants . UNIT _PERCENT : constants . UNIT _POINT ;
2017-01-04 04:33:39 -08:00
asNumber = parseFloat ( value ) ;
}
2017-02-20 05:31:20 -08:00
if ( ! Object . prototype . hasOwnProperty . call ( methods , unit ) )
throw new Error ( ` Failed to execute " ${ fnName } ": Unsupported unit. ` ) ;
if ( asNumber !== undefined ) {
return methods [ unit ] . call ( this , ... args , asNumber ) ;
} else {
return methods [ unit ] . call ( this , ... args ) ;
}
2017-01-04 04:33:39 -08:00
} ) ;
}
2017-01-02 02:22:45 -08:00
patch ( lib . Node . prototype , ` free ` , function ( ) {
// Since we handle the memory allocation ourselves (via lib.Node.create), we also need to handle the deallocation
lib . Node . destroy ( this ) ;
} ) ;
patch ( lib . Node . prototype , ` freeRecursive ` , function ( ) {
for ( let t = 0 , T = this . getChildCount ( ) ; t < T ; ++ t )
this . getChild ( 0 ) . freeRecursive ( ) ;
this . free ( ) ;
} ) ;
patch ( lib . Node . prototype , ` setMeasureFunc ` , function ( original , measureFunc ) {
// This patch is just a convenience patch, since it helps write more idiomatic source code (such as .setMeasureFunc(null))
// We also automatically convert the return value of the measureFunc to a Size object, so that we can return anything that has .width and .height properties
if ( measureFunc ) {
return original . call ( this , ( ... args ) => Size . fromJS ( measureFunc ( ... args ) ) ) ;
} else {
return this . unsetMeasureFunc ( ) ;
}
} ) ;
patch ( lib . Node . prototype , ` calculateLayout ` , function ( original , width = constants . UNDEFINED , height = constants . UNDEFINED , direction = constants . DIRECTION _LTR ) {
// Just a small patch to add support for the function default parameters
return original . call ( this , width , height , direction ) ;
} ) ;
function setExperimentalFeatureEnabled ( ... args ) {
return lib . setExperimentalFeatureEnabled ( ... args ) ;
}
function isExperimentalFeatureEnabled ( ... args ) {
return lib . isExperimentalFeatureEnabled ( ... args ) ;
}
function getInstanceCount ( ... args ) {
return lib . getInstanceCount ( ... args ) ;
}
bind ( ` Layout ` , Layout ) ;
bind ( ` Size ` , Size ) ;
2017-01-04 04:33:39 -08:00
bind ( ` Value ` , Value ) ;
2017-01-02 02:22:45 -08:00
return Object . assign ( {
Node : lib . Node ,
Layout ,
Size ,
2017-01-04 04:33:39 -08:00
Value ,
2017-01-02 02:22:45 -08:00
setExperimentalFeatureEnabled ,
isExperimentalFeatureEnabled ,
getInstanceCount
} , constants ) ;
} ;