@@ -4271,55 +4271,68 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
4271
4271
offsetLeft : 0
4272
4272
} , options || { } ) ;
4273
4273
4274
- var docEl = document . documentElement ;
4275
-
4274
+ // Find page position of source.
4276
4275
source = $ ( source ) ;
4277
4276
element = $ ( element ) ;
4278
4277
var p , delta , layout , styles = { } ;
4279
4278
4279
+ var isAbsolute = Element . getStyle ( element , 'position' ) === 'absolute' ;
4280
+ var parent = Element . getOffsetParent ( element ) ;
4281
+
4280
4282
if ( options . setLeft || options . setTop ) {
4283
+ // We start by measuring the source's viewport offset.
4281
4284
p = Element . viewportOffset ( source ) ;
4285
+
4286
+ // If the element we're altering is `position: fixed`, that's all the
4287
+ // information we need: later we'll apply that offset to the `top` and
4288
+ // `left` properties directly.
4282
4289
delta = [ 0 , 0 ] ;
4283
- if ( Element . getStyle ( element , 'position' ) === 'absolute' ) {
4284
- var parent = Element . getOffsetParent ( element ) ;
4285
- if ( parent !== document . body ) delta = Element . viewportOffset ( parent ) ;
4290
+
4291
+ // But if it's `position: absolute`, we have to know where its offset
4292
+ // parent is positioned and take those measurements into account as
4293
+ // well.
4294
+ if ( isAbsolute && parent !== document . body ) {
4295
+ delta = Element . viewportOffset ( parent ) ;
4286
4296
}
4287
4297
}
4288
4298
4289
4299
function pageScrollXY ( ) {
4290
4300
var x = 0 , y = 0 ;
4291
4301
if ( Object . isNumber ( window . pageXOffset ) ) {
4302
+ // Modern browsers.
4292
4303
x = window . pageXOffset ;
4293
4304
y = window . pageYOffset ;
4294
4305
} else if ( document . body && ( document . body . scrollLeft || document . body . scrollTop ) ) {
4295
4306
x = document . body . scrollLeft ;
4296
4307
y = document . body . scrollTop ;
4297
- } else if ( docEl && ( docEl . scrollLeft || docEl . scrollTop ) ) {
4298
- x = docEl . scrollLeft ;
4299
- y = docEl . scrollTop ;
4300
4308
}
4301
4309
return { x : x , y : y } ;
4302
4310
}
4303
4311
4304
- var pageXY = pageScrollXY ( ) ;
4305
-
4306
-
4307
- if ( options . setWidth || options . setHeight ) {
4308
- layout = Element . getLayout ( source ) ;
4309
- }
4312
+ // When the offset parent is the document body, we need to account for
4313
+ // scroll offsets when we set `top` and `left`. (Unless the element is
4314
+ // `position: fixed`; in that case we should always ignore scroll
4315
+ // position.)
4316
+ var pageXY = ( isAbsolute && parent === document . body ) ? pageScrollXY ( ) : { x : 0 , y : 0 } ;
4310
4317
4318
+ // Set position.
4311
4319
if ( options . setLeft )
4312
4320
styles . left = ( p [ 0 ] + pageXY . x - delta [ 0 ] + options . offsetLeft ) + 'px' ;
4313
4321
if ( options . setTop )
4314
4322
styles . top = ( p [ 1 ] + pageXY . y - delta [ 1 ] + options . offsetTop ) + 'px' ;
4315
4323
4316
- var currentLayout = element . getLayout ( ) ;
4324
+ if ( options . setWidth || options . setHeight ) {
4325
+ layout = Element . getLayout ( source ) ;
4317
4326
4318
- if ( options . setWidth ) {
4319
- styles . width = layout . get ( 'width' ) + 'px' ;
4320
- }
4321
- if ( options . setHeight ) {
4322
- styles . height = layout . get ( 'height' ) + 'px' ;
4327
+ // Use content box when setting width/height. If padding/border are
4328
+ // different between source and target, that's for the user to fix;
4329
+ // there's no good option for us.
4330
+ if ( options . setWidth ) {
4331
+ styles . width = layout . get ( 'width' ) + 'px' ;
4332
+ }
4333
+ if ( options . setHeight ) {
4334
+ styles . height = layout . get ( 'height' ) + 'px' ;
4335
+ }
4323
4336
}
4324
4337
4325
4338
return Element . setStyle ( element , styles ) ;
0 commit comments