@ -151,9 +151,15 @@
BI . extend ( BI . DOM , {
getLeftPosition : function ( combo , popup , extraWidth ) {
getLeftPosition : function ( combo , popup , extraWidth , container ) {
var el = combo . element ;
var popupEl = popup . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var popupElRect = popupEl [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { left : 0 } ;
return {
left : combo . element . offset ( ) . left - popup . element . outerWidth ( ) - ( extraWidth || 0 )
left : elRect . left - containerRect . left - popupElRect . width - ( extraWidth || 0 )
} ;
} ,
@ -163,10 +169,13 @@
} ;
} ,
getRightPosition : function ( combo , popup , extraWidth ) {
getRightPosition : function ( combo , popup , extraWidth , container ) {
var el = combo . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { left : 0 } ;
return {
left : el . offset ( ) . left + el . outerWidth ( ) + ( extraWidth || 0 )
left : elRect . left + elRect . width - containerRect . left + ( extraWidth || 0 )
} ;
} ,
@ -177,16 +186,25 @@
} ;
} ,
getTopPosition : function ( combo , popup , extraHeight ) {
getTopPosition : function ( combo , popup , extraHeight , container ) {
var el = combo . element ;
var popupEl = popup . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var popupElRect = popupEl [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
return {
top : combo . element . offset ( ) . top - popup . element . outerHeight ( ) - ( extraHeight || 0 )
top : elRect . top - containerRect . top - popupElRect . height - ( extraHeight || 0 )
} ;
} ,
getBottomPosition : function ( combo , popup , extraHeight ) {
getBottomPosition : function ( combo , popup , extraHeight , container ) {
var el = combo . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
return {
top : el . offset ( ) . top + el . outerHeight ( ) + ( extraHeight || 0 )
top : elRect . top - containerRect . top + elRect . height + ( extraHeight || 0 )
} ;
} ,
@ -230,18 +248,19 @@
return windowBounds . height - combo . element . offset ( ) . top - combo . element . bounds ( ) . height >= combo . element . offset ( ) . top ;
} ,
_getLeftAlignPosition : function ( combo , popup , extraWidth ) {
_getLeftAlignPosition : function ( combo , popup , extraWidth , container ) {
var viewBounds = popup . element . bounds ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
var left = combo . element . offset ( ) . left + extraWidth ;
var left = combo . element . offset ( ) . left - ( container ? container . getBoundingClientRect ( ) . left : 0 ) + extraWidth ;
if ( left + viewBounds . width > windowBounds . width ) {
left = windowBounds . width - viewBounds . width ;
}
return left ;
} ,
getLeftAlignPosition : function ( combo , popup , extraWidth ) {
var left = this . _getLeftAlignPosition ( combo , popup , extraWidth ) ;
getLeftAlignPosition : function ( combo , popup , extraWidth , container ) {
var left = this . _getLeftAlignPosition ( combo , popup , extraWidth , container ) ;
var dir = "" ;
// 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0
if ( left < 0 ) {
@ -297,13 +316,14 @@
} ;
} ,
getTopAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight ) {
getTopAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight , container ) {
var comboOffset = combo . element . offset ( ) ;
var comboBounds = combo . element . bounds ( ) , popupBounds = popup . element . bounds ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ,
containerBounds = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
var top , adaptHeight , dir ;
if ( BI . DOM . isBottomSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
top = comboOffset . top + extraHeight ;
top = comboOffset . top - containerBounds . top + extraHeight ;
} else if ( needAdaptHeight ) {
top = comboOffset . top + extraHeight ;
adaptHeight = windowBounds . height - top ;
@ -353,13 +373,15 @@
} ;
} ,
getBottomAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight ) {
getBottomAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight , container ) {
var comboOffset = combo . element . offset ( ) ;
var comboBounds = combo . element . bounds ( ) , popupBounds = popup . element . bounds ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
var comboBounds = combo . element [ 0 ] . getBoundingClientRect ( ) ,
popupBounds = popup . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ,
containerBounds = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
var top , adaptHeight , dir ;
if ( BI . DOM . isTopSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
top = comboOffset . top + comboBounds . height - popup Bounds. heigh t - extraH eight;
top = comboOffset . top + comboBounds . height - container Bounds. top - popupBounds . h eight;
} else if ( needAdaptHeight ) {
top = 0 ;
adaptHeight = comboOffset . top + comboBounds . height - extraHeight ;
@ -446,7 +468,7 @@
} ;
} ,
getComboPositionByDirections : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions ) {
getComboPositionByDirections : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , container ) {
extraWidth || ( extraWidth = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
var i , direct ;
@ -483,11 +505,11 @@
if ( ! isNeedAdaptHeight ) {
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? 0 : extraHeight ;
if ( BI . DOM . isLeftSpaceEnough ( combo , popup , tW ) ) {
left = BI . DOM . getLeftPosition ( combo , popup , tW ) . left ;
left = BI . DOM . getLeftPosition ( combo , popup , tW , container ) . left ;
if ( topBottom [ 0 ] === "bottom" ) {
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
} else {
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
}
pos . dir = "left," + pos . dir ;
if ( tbFirst ) {
@ -503,11 +525,11 @@
if ( ! isNeedAdaptHeight ) {
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isRightSpaceEnough ( combo , popup , tW ) ) {
left = BI . DOM . getRightPosition ( combo , popup , tW ) . left ;
left = BI . DOM . getRightPosition ( combo , popup , tW , container ) . left ;
if ( topBottom [ 0 ] === "bottom" ) {
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
} else {
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
}
pos . dir = "right," + pos . dir ;
if ( tbFirst ) {
@ -522,11 +544,11 @@
case "top" :
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isTopSpaceEnough ( combo , popup , tH ) ) {
top = BI . DOM . getTopPosition ( combo , popup , tH ) . top ;
top = BI . DOM . getTopPosition ( combo , popup , tH , container ) . top ;
if ( leftRight [ 0 ] === "right" ) {
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , needAdaptHeight ) ;
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , container ) ;
} else {
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW ) ;
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW , container ) ;
}
pos . dir = "top," + pos . dir ;
if ( lrFirst ) {
@ -543,11 +565,11 @@
case "bottom" :
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isBottomSpaceEnough ( combo , popup , tH ) ) {
top = BI . DOM . getBottomPosition ( combo , popup , tH ) . top ;
top = BI . DOM . getBottomPosition ( combo , popup , tH , container ) . top ;
if ( leftRight [ 0 ] === "right" ) {
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , needAdaptHeight ) ;
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , container ) ;
} else {
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW ) ;
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW , container ) ;
}
pos . dir = "bottom," + pos . dir ;
if ( lrFirst ) {
@ -648,13 +670,13 @@
} ,
getComboPosition : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , offsetStyle ) {
getComboPosition : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , offsetStyle , container ) {
extraWidth || ( extraWidth = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
var bodyHeight = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) . height - extraHeight ;
var maxHeight = Math . min ( popup . attr ( "maxHeight" ) || bodyHeight , bodyHeight ) ;
popup . resetHeight && popup . resetHeight ( maxHeight ) ;
var position = BI . DOM . getComboPositionByDirections ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions || [ "bottom" , "top" , "right" , "left" ] ) ;
var position = BI . DOM . getComboPositionByDirections ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions || [ "bottom" , "top" , "right" , "left" ] , container ) ;
switch ( offsetStyle ) {
case "center" :
if ( position . change ) {
@ -679,6 +701,32 @@
popup . resetHeight && popup . resetHeight ( Math . min ( bodyHeight - position . top , maxHeight ) ) ;
}
return position ;
} ,
/ * *
* 获取position : fixed相对定位的元素
* /
getPositionRelativeContainingBlock : function ( element ) {
if ( [ 'html' , 'body' , '#document' ] . indexOf ( ( element . nodeName || '' ) . toLowerCase ( ) ) >= 0 ) {
// $FlowFixMe[incompatible-return]: assume body is always available
return element . ownerDocument . body ;
}
function isExcept ( node ) {
var _computedStyle = getComputedStyle ( node ) ;
var transform = _computedStyle . transform ;
var perspective = _computedStyle . perspective ;
var filter = _computedStyle . filter ;
var willChange = _computedStyle [ "will-change" ] ;
return [ transform , perspective , filter ] . some ( value => value !== 'none' ) || ( willChange === "transform" ) ;
}
if ( isExcept ( element ) ) {
return element ;
}
return BI . DOM . getPositionRelativeContainingBlock ( element . parentNode ) ;
} ,
} ) ;
} ) ( ) ;