| 537 | }; |
| 538 | |
| 539 | function getExpectations( htmlPos, bodyPos, scrollTop, scrollLeft ) { |
| 540 | |
| 541 | // Initialize data about page elements |
| 542 | var expectations = { |
| 543 | "documentElement": htmlProps( htmlPos ), |
| 544 | "body": bodyProps( bodyPos ), |
| 545 | "relative": divProps( "relative", "body" ), |
| 546 | "relative-relative": divProps( "relative", "relative" ), |
| 547 | "relative-absolute": divProps( "absolute", "relative" ), |
| 548 | "absolute": divProps( "absolute", "body" ), |
| 549 | "absolute-relative": divProps( "relative", "absolute" ), |
| 550 | "absolute-absolute": divProps( "absolute", "absolute" ), |
| 551 | "fixed": divProps( "fixed" ), |
| 552 | "fixed-relative": divProps( "relative", "fixed" ), |
| 553 | "fixed-absolute": divProps( "absolute", "fixed" ) |
| 554 | }; |
| 555 | |
| 556 | // Define position and offset expectations for page elements |
| 557 | supportjQuery.each( expectations, function( id, props ) { |
| 558 | var parent = expectations[ props.parent ], |
| 559 | |
| 560 | // position() relates an element's margin box to its offset parent's padding box |
| 561 | pos = props.pos = { |
| 562 | top: props.top, |
| 563 | left: props.left |
| 564 | }, |
| 565 | |
| 566 | // offset() relates an element's border box to the document origin |
| 567 | offset = props.offset = { |
| 568 | top: pos.top + props.marginTop, |
| 569 | left: pos.left + props.marginLeft |
| 570 | }; |
| 571 | |
| 572 | // Account for ancestors differently by element position |
| 573 | // fixed: ignore them |
| 574 | // absolute: offset includes offsetParent offset+border |
| 575 | // relative: position includes parent padding (and also position+margin+border when |
| 576 | // parent is not offsetParent); offset includes parent offset+border+padding |
| 577 | // static: same as relative |
| 578 | for ( ; parent; parent = expectations[ parent.parent ] ) { |
| 579 | |
| 580 | // position:fixed |
| 581 | if ( props.style === "fixed" ) { |
| 582 | break; |
| 583 | } |
| 584 | |
| 585 | // position:absolute bypass |
| 586 | if ( props.style === "absolute" && parent.style === "static" ) { |
| 587 | continue; |
| 588 | } |
| 589 | |
| 590 | // Offset update |
| 591 | offset.top += parent.offset.top + parent.borderTop; |
| 592 | offset.left += parent.offset.left + parent.borderLeft; |
| 593 | if ( props.style !== "absolute" ) { |
| 594 | offset.top += parent.paddingTop; |
| 595 | offset.left += parent.paddingLeft; |
| 596 | |