@@ -110,11 +110,7 @@ function getContainerDimensions(containerNode: Element): Dimensions {
110110  let  scroll : Position  =  { } ; 
111111  let  isPinchZoomedIn  =  ( visualViewport ?. scale  ??  1 )  >  1 ; 
112112
113-   // In the case where the container is `html` or `body` and the container doesn't have something like `position: relative`, 
114-   // then position absolute will be positioned relative to the viewport, also known as the `initial containing block`. 
115-   // That's why we use the visual viewport instead. 
116- 
117-   if  ( containerNode . tagName  ===  'BODY'  ||  containerNode . tagName  ===  'HTML' )  { 
113+   if  ( containerNode . tagName  ===  'BODY' )  { 
118114    let  documentElement  =  document . documentElement ; 
119115    totalWidth  =  documentElement . clientWidth ; 
120116    totalHeight  =  documentElement . clientHeight ; 
@@ -183,13 +179,10 @@ function getDelta(
183179  let  boundarySize  =  boundaryDimensions [ AXIS_SIZE [ axis ] ] ; 
184180  // Calculate the edges of the boundary (accomodating for the boundary padding) and the edges of the overlay. 
185181  // Note that these values are with respect to the visual viewport (aka 0,0 is the top left of the viewport) 
186- 
187-   let  boundaryStartEdge  =   containerOffsetWithBoundary [ axis ]  +  boundaryDimensions . scroll [ AXIS [ axis ] ]  +   padding ; 
188-   let  boundaryEndEdge  =   containerOffsetWithBoundary [ axis ]  +  boundaryDimensions . scroll [ AXIS [ axis ] ]  +  boundarySize  -  padding ; 
189-   // transformed value of the left edge of the overlay 
190-   let  startEdgeOffset  =  offset  -  containerScroll  +  boundaryDimensions . scroll [ AXIS [ axis ] ]  +  containerOffsetWithBoundary [ axis ]  -  boundaryDimensions [ AXIS [ axis ] ] ; 
191-   // transformed value of the right edge of the overlay 
192-   let  endEdgeOffset  =  offset  -  containerScroll  +  size  +  boundaryDimensions . scroll [ AXIS [ axis ] ]   +  containerOffsetWithBoundary [ axis ]  -  boundaryDimensions [ AXIS [ axis ] ] ; 
182+   let  boundaryStartEdge  =  boundaryDimensions . scroll [ AXIS [ axis ] ]  +  padding ; 
183+   let  boundaryEndEdge  =  boundarySize  +  boundaryDimensions . scroll [ AXIS [ axis ] ]  -  padding ; 
184+   let  startEdgeOffset  =  offset  -  containerScroll  +  containerOffsetWithBoundary [ axis ]  -  boundaryDimensions [ AXIS [ axis ] ] ; 
185+   let  endEdgeOffset  =  offset  -  containerScroll  +  size  +  containerOffsetWithBoundary [ axis ]  -  boundaryDimensions [ AXIS [ axis ] ] ; 
193186
194187  // If any of the overlay edges falls outside of the boundary, shift the overlay the required amount to align one of the overlay's 
195188  // edges with the closest boundary edge. 
@@ -241,8 +234,7 @@ function computePosition(
241234  containerOffsetWithBoundary : Offset , 
242235  isContainerPositioned : boolean , 
243236  arrowSize : number , 
244-   arrowBoundaryOffset : number , 
245-   containerDimensions : Dimensions 
237+   arrowBoundaryOffset : number 
246238)  { 
247239  let  { placement,  crossPlacement,  axis,  crossAxis,  size,  crossSize}  =  placementInfo ; 
248240  let  position : Position  =  { } ; 
@@ -263,9 +255,9 @@ function computePosition(
263255
264256  position [ crossAxis ] !  +=  crossOffset ; 
265257
266-   // overlay top or left  overlapping arrow with button bottom or right  
258+   // overlay top overlapping arrow with button bottom 
267259  const  minPosition  =  childOffset [ crossAxis ]  -  overlaySize [ crossSize ]  +  arrowSize  +  arrowBoundaryOffset ; 
268-   // overlay bottom or right  overlapping arrow with button top or left  
260+   // overlay bottom overlapping arrow with button top 
269261  const  maxPosition  =  childOffset [ crossAxis ]  +  childOffset [ crossSize ]  -  arrowSize  -  arrowBoundaryOffset ; 
270262  position [ crossAxis ]  =  clamp ( position [ crossAxis ] ! ,  minPosition ,  maxPosition ) ; 
271263
@@ -274,8 +266,8 @@ function computePosition(
274266    // If the container is positioned (non-static), then we use the container's actual 
275267    // height, as `bottom` will be relative to this height.  But if the container is static, 
276268    // then it can only be the `document.body`, and `bottom` will be relative to _its_ 
277-     // container. 
278-     const  containerHeight  =  ( isContainerPositioned  ? containerOffsetWithBoundary [ size ]  : containerDimensions [ TOTAL_SIZE [ size ] ] ) ; 
269+     // container, which should be as large as boundaryDimensions . 
270+     const  containerHeight  =  ( isContainerPositioned  ? containerOffsetWithBoundary [ size ]  : boundaryDimensions [ TOTAL_SIZE [ size ] ] ) ; 
279271    position [ FLIPPED_DIRECTION [ axis ] ]  =  Math . floor ( containerHeight  -  childOffset [ axis ]  +  offset ) ; 
280272  }  else  { 
281273    position [ axis ]  =  Math . floor ( childOffset [ axis ]  +  childOffset [ size ]  +  offset ) ; 
@@ -291,55 +283,42 @@ function getMaxHeight(
291283  margins : Position , 
292284  padding : number , 
293285  overlayHeight : number , 
294-   heightGrowthDirection : HeightGrowthDirection , 
295-   containerDimensions : Dimensions 
286+   heightGrowthDirection : HeightGrowthDirection 
296287)  { 
297-   const  containerHeight  =  ( isContainerPositioned  ? containerOffsetWithBoundary . height  : containerDimensions [ TOTAL_SIZE . height ] ) ; 
298-   // For cases where position is set via "bottom" instead of "top", we need to calculate the true overlay top 
299-   // with respect to the container . 
300-   let  overlayTop  =  position . top  !=  null  ? position . top  : ( containerHeight  -  ( position . bottom  ??  0 )  -  overlayHeight ) ; 
288+   const  containerHeight  =  ( isContainerPositioned  ? containerOffsetWithBoundary . height  : boundaryDimensions [ TOTAL_SIZE . height ] ) ; 
289+   // For cases where position is set via "bottom" instead of "top", we need to calculate the true overlay top with respect to the boundary. Reverse calculate this with the same method  
290+   // used in computePosition . 
291+   let  overlayTop  =  position . top  !=  null  ? containerOffsetWithBoundary . top   +   position . top  :  containerOffsetWithBoundary . top   +  ( containerHeight  -  ( position . bottom  ??  0 )  -  overlayHeight ) ; 
301292  let  maxHeight  =  heightGrowthDirection  !==  'top'  ?
302293    // We want the distance between the top of the overlay to the bottom of the boundary 
303294    Math . max ( 0 , 
304-       ( boundaryDimensions . height  +  boundaryDimensions . top )  // this is the bottom of the boundary 
295+       ( boundaryDimensions . height  +  boundaryDimensions . top   +   ( boundaryDimensions . scroll . top   ??   0 ) )  // this is the bottom of the boundary 
305296      -  overlayTop  // this is the top of the overlay 
306297      -  ( ( margins . top  ??  0 )  +  ( margins . bottom  ??  0 )  +  padding )  // save additional space for margin and padding 
307298    ) 
308299    // We want the distance between the bottom of the overlay to the top of the boundary 
309300    : Math . max ( 0 , 
310301      ( overlayTop  +  overlayHeight )  // this is the bottom of the overlay 
311-       -  boundaryDimensions . top  // this is the top of the boundary 
302+       -  ( boundaryDimensions . top   +   ( boundaryDimensions . scroll . top   ??   0 ) )  // this is the top of the boundary 
312303      -  ( ( margins . top  ??  0 )  +  ( margins . bottom  ??  0 )  +  padding )  // save additional space for margin and padding 
313304    ) ; 
314305  return  Math . min ( boundaryDimensions . height  -  ( padding  *  2 ) ,  maxHeight ) ; 
315306} 
316307
317308function  getAvailableSpace ( 
318-   boundaryDimensions : Dimensions ,   // boundary 
309+   boundaryDimensions : Dimensions , 
319310  containerOffsetWithBoundary : Offset , 
320-   childOffset : Offset ,   // trigger 
321-   margins : Position ,   // overlay 
322-   padding : number ,   // overlay <-> boundary 
311+   childOffset : Offset , 
312+   margins : Position , 
313+   padding : number , 
323314  placementInfo : ParsedPlacement 
324315)  { 
325316  let  { placement,  axis,  size}  =  placementInfo ; 
326317  if  ( placement  ===  axis )  { 
327-     return  Math . max ( 0 , 
328-       childOffset [ axis ]  // trigger start 
329-       -  boundaryDimensions [ axis ]  // boundary start 
330-       -  ( margins [ axis ]  ??  0 )  // margins usually for arrows or other decorations 
331-       -  margins [ FLIPPED_DIRECTION [ axis ] ] 
332-       -  padding ) ;  // padding between overlay and boundary 
318+     return  Math . max ( 0 ,  childOffset [ axis ]  -  boundaryDimensions [ axis ]  -  ( boundaryDimensions . scroll [ axis ]  ??  0 )  +  containerOffsetWithBoundary [ axis ]  -  ( margins [ axis ]  ??  0 )  -  margins [ FLIPPED_DIRECTION [ axis ] ]  -  padding ) ; 
333319  } 
334320
335-   return  Math . max ( 0 , 
336-     boundaryDimensions [ size ] 
337-     +  boundaryDimensions [ axis ] 
338-      -  childOffset [ axis ] 
339-      -  childOffset [ size ] 
340-      -  ( margins [ axis ]  ??  0 ) 
341-      -  margins [ FLIPPED_DIRECTION [ axis ] ] 
342-      -  padding ) ; 
321+   return  Math . max ( 0 ,  boundaryDimensions [ size ]  +  boundaryDimensions [ axis ]  +  boundaryDimensions . scroll [ axis ]  -  containerOffsetWithBoundary [ axis ]  -  childOffset [ axis ]  -  childOffset [ size ]  -  ( margins [ axis ]  ??  0 )  -  margins [ FLIPPED_DIRECTION [ axis ] ]  -  padding ) ; 
343322} 
344323
345324export  function  calculatePositionInternal ( 
@@ -362,7 +341,7 @@ export function calculatePositionInternal(
362341) : PositionResult  { 
363342  let  placementInfo  =  parsePlacement ( placementInput ) ; 
364343  let  { size,  crossAxis,  crossSize,  placement,  crossPlacement}  =  placementInfo ; 
365-   let  position  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  placementInfo ,  offset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ,   containerDimensions ) ; 
344+   let  position  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  placementInfo ,  offset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ) ; 
366345  let  normalizedOffset  =  offset ; 
367346  let  space  =  getAvailableSpace ( 
368347    boundaryDimensions , 
@@ -376,8 +355,7 @@ export function calculatePositionInternal(
376355  // Check if the scroll size of the overlay is greater than the available space to determine if we need to flip 
377356  if  ( flip  &&  scrollSize [ size ]  >  space )  { 
378357    let  flippedPlacementInfo  =  parsePlacement ( `${ FLIPPED_DIRECTION [ placement ] }   ${ crossPlacement }  `  as  Placement ) ; 
379-     let  flippedPosition  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  flippedPlacementInfo ,  offset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ,  containerDimensions ) ; 
380- 
358+     let  flippedPosition  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  flippedPlacementInfo ,  offset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ) ; 
381359    let  flippedSpace  =  getAvailableSpace ( 
382360      boundaryDimensions , 
383361      containerOffsetWithBoundary , 
@@ -422,8 +400,7 @@ export function calculatePositionInternal(
422400    margins , 
423401    padding , 
424402    overlaySize . height , 
425-     heightGrowthDirection , 
426-     containerDimensions 
403+     heightGrowthDirection 
427404  ) ; 
428405
429406  if  ( userSetMaxHeight  &&  userSetMaxHeight  <  maxHeight )  { 
@@ -432,7 +409,7 @@ export function calculatePositionInternal(
432409
433410  overlaySize . height  =  Math . min ( overlaySize . height ,  maxHeight ) ; 
434411
435-   position  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  placementInfo ,  normalizedOffset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ,   containerDimensions ) ; 
412+   position  =  computePosition ( childOffset ,  boundaryDimensions ,  overlaySize ,  placementInfo ,  normalizedOffset ,  crossOffset ,  containerOffsetWithBoundary ,  isContainerPositioned ,  arrowSize ,  arrowBoundaryOffset ) ; 
436413  delta  =  getDelta ( crossAxis ,  position [ crossAxis ] ! ,  overlaySize [ crossSize ] ,  boundaryDimensions ,  containerDimensions ,  padding ,  containerOffsetWithBoundary ) ; 
437414  position [ crossAxis ] !  +=  delta ; 
438415
@@ -530,7 +507,7 @@ export function calculatePosition(opts: PositionOpts): PositionResult {
530507  // If the container is the HTML element wrapping the body element, the retrieved scrollTop/scrollLeft will be equal to the 
531508  // body element's scroll. Set the container's scroll values to 0 since the overlay's edge position value in getDelta don't then need to be further offset 
532509  // by the container scroll since they are essentially the same containing element and thus in the same coordinate system 
533-   let  containerOffsetWithBoundary : Offset  =  boundaryElement . tagName  ===  'BODY'  ? getOffset ( container ,  false )  : getPosition ( boundaryElement ,   container ,   false ) ; 
510+   let  containerOffsetWithBoundary : Offset  =  boundaryElement . tagName  ===  'BODY'  ? getOffset ( container ,  false )  : getPosition ( container ,  boundaryElement ,  false ) ; 
534511  if  ( container . tagName  ===  'HTML'  &&  boundaryElement . tagName  ===  'BODY' )  { 
535512    containerDimensions . scroll . top  =  0 ; 
536513    containerDimensions . scroll . left  =  0 ; 
@@ -559,7 +536,7 @@ export function calculatePosition(opts: PositionOpts): PositionResult {
559536export  function  getRect ( node : Element ,  ignoreScale : boolean )  { 
560537  let  { top,  left,  width,  height}  =  node . getBoundingClientRect ( ) ; 
561538
562-   // Use offsetWidth and offsetHeight if this is an HTML element, so that 
539+   // Use offsetWidth and offsetHeight if this is an HTML element, so that   
563540  // the size is not affected by scale transforms. 
564541  if  ( ignoreScale  &&  node  instanceof  node . ownerDocument . defaultView ! . HTMLElement )  { 
565542    width  =  node . offsetWidth ; 
0 commit comments