@ -151,9 +151,15 @@
BI . extend ( BI . DOM , {
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 {
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 el = combo . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { left : 0 } ;
return {
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 {
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 el = combo . element ;
var elRect = el [ 0 ] . getBoundingClientRect ( ) ;
var containerRect = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
return {
return {
top : el . offset ( ) . top + el . outerHeight ( ) + ( extraHeight || 0 )
top : elRect . top - containerRect . top + elRect . height + ( extraHeight || 0 )
} ;
} ;
} ,
} ,
@ -201,9 +219,9 @@
} ,
} ,
isRightSpaceEnough : function ( combo , popup , extraWidth ) {
isRightSpaceEnough : function ( combo , popup , extraWidth ) {
var viewBounds = popup . element . bounds ( ) ,
var viewBounds = popup . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
viewportBounds = document . documentElement . getBoundingClientRect ( ) ;
return BI . DOM . getRightPosition ( combo , popup , extraWidth ) . left + viewBounds . width <= window Bounds. width ;
return BI . DOM . getRightPosition ( combo , popup , extraWidth ) . left + viewBounds . width <= viewport Bounds. width ;
} ,
} ,
isInnerRightSpaceEnough : function ( combo , popup , extraWidth ) {
isInnerRightSpaceEnough : function ( combo , popup , extraWidth ) {
@ -215,9 +233,9 @@
} ,
} ,
isBottomSpaceEnough : function ( combo , popup , extraHeight ) {
isBottomSpaceEnough : function ( combo , popup , extraHeight ) {
var viewBounds = popup . element . bounds ( ) ,
var viewBounds = popup . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
viewportBounds = document . documentElement . getBoundingClientRect ( ) ;
return BI . DOM . getBottomPosition ( combo , popup , extraHeight ) . top + viewBounds . height <= window Bounds. height ;
return BI . DOM . getBottomPosition ( combo , popup , extraHeight ) . top + viewBounds . height <= viewport Bounds. height ;
} ,
} ,
isRightSpaceLarger : function ( combo ) {
isRightSpaceLarger : function ( combo ) {
@ -230,18 +248,19 @@
return windowBounds . height - combo . element . offset ( ) . top - combo . element . bounds ( ) . height >= combo . element . offset ( ) . top ;
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 ( ) ,
var viewBounds = popup . element . bounds ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . 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 ) {
if ( left + viewBounds . width > windowBounds . width ) {
left = windowBounds . width - viewBounds . width ;
left = windowBounds . width - viewBounds . width ;
}
}
return left ;
return left ;
} ,
} ,
getLeftAlignPosition : function ( combo , popup , extraWidth ) {
getLeftAlignPosition : function ( combo , popup , extraWidth , container ) {
var left = this . _getLeftAlignPosition ( combo , popup , extraWidth ) ;
var left = this . _getLeftAlignPosition ( combo , popup , extraWidth , container ) ;
var dir = "" ;
var dir = "" ;
// 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0
// 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0
if ( left < 0 ) {
if ( left < 0 ) {
@ -297,24 +316,26 @@
} ;
} ;
} ,
} ,
getTopAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight ) {
getTopAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight , container ) {
var comboOffset = combo . element . offset ( ) ;
var comboOffset = combo . element . offset ( ) ;
var comboBounds = combo . element . bounds ( ) , popupBounds = popup . element . bounds ( ) ,
var comboBounds = combo . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
popupBounds = popup . element [ 0 ] . getBoundingClientRect ( ) ,
viewportBounds = document . documentElement . getBoundingClientRect ( ) ,
containerBounds = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
var top , adaptHeight , dir ;
var top , adaptHeight , dir ;
if ( BI . DOM . isBottomSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
if ( BI . DOM . isBottomSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
top = comboOffset . top + extraHeight ;
top = comboOffset . top - containerBounds . top + extraHeight ;
} else if ( needAdaptHeight ) {
} else if ( needAdaptHeight ) {
top = comboOffset . top + extraHeight ;
top = comboBounds . top - containerBounds . top + extraHeight ;
adaptHeight = window Bounds. height - top ;
adaptHeight = viewport Bounds. height - comboBounds . top ;
} else if ( BI . DOM . isTopSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
} else if ( BI . DOM . isTopSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
// 下方空间不足且不允许调整高度的情况下,优先使用上对齐
// 下方空间不足且不允许调整高度的情况下,优先使用上对齐
top = comboOffset . top + comboBounds . height - popupBounds . height - extraHeight ;
top = comboBounds . top + comboBounds . height - popupBounds . height - containerBounds . top - extraHeight ;
dir = "top" ;
dir = "top" ;
} else {
} else {
top = window Bounds. height - popupBounds . height ;
top = viewport Bounds. height - popupBounds . height ;
if ( top < extraHeight ) {
if ( top < extraHeight ) {
adaptHeight = window Bounds. height - extraHeight ;
adaptHeight = viewport Bounds. height - extraHeight ;
}
}
}
}
if ( top < extraHeight ) {
if ( top < extraHeight ) {
@ -353,19 +374,21 @@
} ;
} ;
} ,
} ,
getBottomAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight ) {
getBottomAlignPosition : function ( combo , popup , extraHeight , needAdaptHeight , container ) {
var comboOffset = combo . element . offset ( ) ;
var comboOffset = combo . element . offset ( ) ;
var comboBounds = combo . element . bounds ( ) , popupBounds = popup . element . bounds ( ) ,
var comboBounds = combo . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ;
popupBounds = popup . element [ 0 ] . getBoundingClientRect ( ) ,
windowBounds = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) ,
containerBounds = container ? container . getBoundingClientRect ( ) : { top : 0 } ;
var top , adaptHeight , dir ;
var top , adaptHeight , dir ;
if ( BI . DOM . isTopSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
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 ) {
} else if ( needAdaptHeight ) {
top = 0 ;
top = 0 - containerBounds . top ;
adaptHeight = comboOffset . top + comboBounds . height - extraHeight ;
adaptHeight = comboBounds . top + comboBounds . height - extraHeight ;
} else if ( BI . DOM . isBottomSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
} else if ( BI . DOM . isBottomSpaceEnough ( combo , popup , - 1 * comboBounds . height + extraHeight ) ) {
// 上方空间不足且不允许调整高度的情况下,优先使用下对齐
// 上方空间不足且不允许调整高度的情况下,优先使用下对齐
top = comboOffset . top + extraHeight ;
top = comboOffset . top - containerBounds . top + extraHeight ;
dir = "bottom" ;
dir = "bottom" ;
} else {
} else {
top = 0 ;
top = 0 ;
@ -373,7 +396,7 @@
adaptHeight = windowBounds . height - extraHeight ;
adaptHeight = windowBounds . height - extraHeight ;
}
}
}
}
if ( top < 0 ) {
if ( top + containerBounds . top < 0 ) {
top = 0 ;
top = 0 ;
}
}
return adaptHeight ? {
return adaptHeight ? {
@ -446,7 +469,7 @@
} ;
} ;
} ,
} ,
getComboPositionByDirections : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions ) {
getComboPositionByDirections : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , container ) {
extraWidth || ( extraWidth = 0 ) ;
extraWidth || ( extraWidth = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
var i , direct ;
var i , direct ;
@ -483,11 +506,11 @@
if ( ! isNeedAdaptHeight ) {
if ( ! isNeedAdaptHeight ) {
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? 0 : extraHeight ;
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? 0 : extraHeight ;
if ( BI . DOM . isLeftSpaceEnough ( combo , popup , tW ) ) {
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" ) {
if ( topBottom [ 0 ] === "bottom" ) {
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
} else {
} else {
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
}
}
pos . dir = "left," + pos . dir ;
pos . dir = "left," + pos . dir ;
if ( tbFirst ) {
if ( tbFirst ) {
@ -503,11 +526,11 @@
if ( ! isNeedAdaptHeight ) {
if ( ! isNeedAdaptHeight ) {
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? extraWidth : extraHeight ;
var tW = tbFirst ? extraHeight : extraWidth , tH = tbFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isRightSpaceEnough ( combo , popup , tW ) ) {
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" ) {
if ( topBottom [ 0 ] === "bottom" ) {
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getTopAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
} else {
} else {
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight ) ;
pos = BI . DOM . getBottomAlignPosition ( combo , popup , tH , needAdaptHeight , container ) ;
}
}
pos . dir = "right," + pos . dir ;
pos . dir = "right," + pos . dir ;
if ( tbFirst ) {
if ( tbFirst ) {
@ -522,11 +545,11 @@
case "top" :
case "top" :
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isTopSpaceEnough ( combo , popup , tH ) ) {
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" ) {
if ( leftRight [ 0 ] === "right" ) {
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , needAdaptHeight ) ;
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , container ) ;
} else {
} else {
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW ) ;
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW , container ) ;
}
}
pos . dir = "top," + pos . dir ;
pos . dir = "top," + pos . dir ;
if ( lrFirst ) {
if ( lrFirst ) {
@ -543,11 +566,11 @@
case "bottom" :
case "bottom" :
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
var tW = lrFirst ? extraHeight : extraWidth , tH = lrFirst ? extraWidth : extraHeight ;
if ( BI . DOM . isBottomSpaceEnough ( combo , popup , tH ) ) {
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" ) {
if ( leftRight [ 0 ] === "right" ) {
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , needAdaptHeight ) ;
pos = BI . DOM . getLeftAlignPosition ( combo , popup , tW , container ) ;
} else {
} else {
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW ) ;
pos = BI . DOM . getRightAlignPosition ( combo , popup , tW , container ) ;
}
}
pos . dir = "bottom," + pos . dir ;
pos . dir = "bottom," + pos . dir ;
if ( lrFirst ) {
if ( lrFirst ) {
@ -635,7 +658,7 @@
firstDir = "top" ;
firstDir = "top" ;
}
}
if ( leftRight [ 0 ] === "right" ) {
if ( leftRight [ 0 ] === "right" ) {
pos = BI . DOM . getLeftAlignPosition ( combo , popup , extraWidth , needAdaptHeight ) ;
pos = BI . DOM . getLeftAlignPosition ( combo , popup , extraWidth ) ;
pos . top = top ;
pos . top = top ;
pos . dir = firstDir + "," + pos . dir ;
pos . dir = firstDir + "," + pos . dir ;
return pos ;
return pos ;
@ -648,13 +671,13 @@
} ,
} ,
getComboPosition : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , offsetStyle ) {
getComboPosition : function ( combo , popup , extraWidth , extraHeight , needAdaptHeight , directions , offsetStyle , positionRelativeElement ) {
extraWidth || ( extraWidth = 0 ) ;
extraWidth || ( extraWidth = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
extraHeight || ( extraHeight = 0 ) ;
var bodyHeight = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) . height - extraHeight ;
var bodyHeight = BI . Widget . _renderEngine . createElement ( "body" ) . bounds ( ) . height - extraHeight ;
var maxHeight = Math . min ( popup . attr ( "maxHeight" ) || bodyHeight , bodyHeight ) ;
var maxHeight = Math . min ( popup . attr ( "maxHeight" ) || bodyHeight , bodyHeight ) ;
popup . resetHeight && popup . resetHeight ( maxHeight ) ;
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" ] , positionRelativeElement ) ;
switch ( offsetStyle ) {
switch ( offsetStyle ) {
case "center" :
case "center" :
if ( position . change ) {
if ( position . change ) {
@ -676,9 +699,35 @@
break ;
break ;
}
}
if ( needAdaptHeight === true ) {
if ( needAdaptHeight === true ) {
popup . resetHeight && popup . resetHeight ( Math . min ( bodyHeight - position . top , maxHeight ) ) ;
popup . resetHeight && popup . resetHeight ( Math . min ( bodyHeight - position . top + ( positionRelativeElement ? positionRelativeElement . getBoundingClientRect ( ) . top : 0 ) , maxHeight ) ) ;
}
}
return position ;
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 ) ;
} ,
} ) ;
} ) ;
} ) ( ) ;
} ) ( ) ;