| | 17 | |
| | 18 | // all the V/H object members below are to reuse code for both directions |
| | 19 | function addPseudoAttrs(element){ |
| | 20 | // use border box for node since margin visibility is least important |
| | 21 | // use content box for parents since we don't care about parent border and padding |
| | 22 | // use HTML size instead of BODY size since that's where the scrollbars are defined |
| | 23 | var parent = element.parentNode; |
| | 24 | var nodeBox = dojo._getBorderBox(element); |
| | 25 | if(element.tagName=="BODY"){ |
| | 26 | htmlBox = dojo._getBorderBox(parent); |
| | 27 | // this varies depending on browser and DOCTYPE |
| | 28 | if(htmlBox.w < nodeBox.w){ nodeBox.w = htmlBox.w; } |
| | 29 | if(htmlBox.h < nodeBox.h){ nodeBox.h = htmlBox.h; } |
| | 30 | } |
| | 31 | size = { H: nodeBox.w, V: nodeBox.h }; |
| | 32 | var start = { H:element.offsetLeft, V:element.offsetTop }; |
| | 33 | // check if this node and its parent share the same offsetParent |
| | 34 | element._startIsRelative = !(parent && parent.tagName && parent.offsetParent == element.offsetParent); |
| | 35 | var bp = dojo._getBorderExtents(element); |
| | 36 | if(element != node){ // parent = skip border |
| | 37 | start.H += bp.l; |
| | 38 | start.V += bp.t; |
| | 39 | }else{ // original node = add border to size |
| | 40 | size.H += bp.w; |
| | 41 | size.V += bp.h; |
| | 42 | } |
| | 43 | // FIXME: _getBorderBox/FF2 workaround |
| | 44 | var fudgeStart = { H:0, V:0 }; |
| | 45 | if(dojo.isFF == 2){ |
| | 46 | var parent = element.parentNode; |
| | 47 | if(parent && parent.tagName){ |
| | 48 | var bp = dojo._getBorderExtents(parent); |
| | 49 | fudgeStart.H += bp.l; |
| | 50 | fudgeStart.V += bp.t; |
| | 51 | } |
| | 52 | } |
| | 53 | element._size = size; |
| | 54 | element._start = start; |
| | 55 | element._fudgeStart = fudgeStart; |
| | 56 | } |
| | 57 | |
| | 58 | var r2l = !dojo._isBodyLtr(); |
| | 59 | node = dojo.byId(node); |
| 18 | | var parentBottom = parent.scrollTop + dojo.marginBox(parent).h; //PORT was getBorderBox |
| 19 | | var nodeBottom = node.offsetTop + dojo.marginBox(node).h; |
| 20 | | if(parentBottom < nodeBottom){ |
| 21 | | parent.scrollTop += (nodeBottom - parentBottom); |
| 22 | | }else if(parent.scrollTop > node.offsetTop){ |
| 23 | | parent.scrollTop -= (parent.scrollTop - node.offsetTop); |
| | 61 | addPseudoAttrs(node); |
| | 62 | var xy = { V: null, H: null }; |
| | 63 | while(parent && parent.tagName){ // tagName check needed for IE since HTML node has a tag-less parent |
| | 64 | addPseudoAttrs(parent); |
| | 65 | // for both x and y directions |
| | 66 | for (var dir in xy){ |
| | 67 | var scrollAttr = (dir=="H")? "scrollLeft" : "scrollTop"; |
| | 68 | var oldScroll = parent[scrollAttr]; |
| | 69 | nodeRelativeOffset = node._start[dir] + node._fudgeStart[dir] - (node._startIsRelative? 0 : parent._start[dir]) - oldScroll; |
| | 70 | if(parent._size[dir] < node._size[dir]){ // see if the node will be clipped |
| | 71 | node._size[dir] = parent._size[dir]; // simplify calculations |
| | 72 | } |
| | 73 | var overflow = nodeRelativeOffset + node._size[dir] - parent._size[dir]; |
| | 74 | var underflow = nodeRelativeOffset; |
| | 75 | var scrollAmount; |
| | 76 | // see if we should scroll forward or backward |
| | 77 | if(underflow <= 0){ |
| | 78 | scrollAmount = underflow; |
| | 79 | }else if(overflow <= 0){ |
| | 80 | scrollAmount = 0; |
| | 81 | }else if(underflow < overflow){ |
| | 82 | scrollAmount = underflow; |
| | 83 | }else{ |
| | 84 | scrollAmount = overflow; |
| | 85 | } |
| | 86 | var newScroll = scrollAmount + oldScroll; |
| | 87 | if(newScroll < 0 && r2l && dir=="H"){ // safari and IE need an adjustment since inline nodes return the wrong offsetLeft in right-to-left mode |
| | 88 | newScroll += parent.scrollWidth - parent.clientWidth; |
| | 89 | } |
| | 90 | parent[scrollAttr] = newScroll; // actually perform the scroll |
| | 91 | nodeRelativeOffset -= parent[scrollAttr] - oldScroll; |
| | 92 | parent._size[dir] = node._size[dir]; // now we only want to show this portion of the parent |
| | 93 | parent._start[dir] += nodeRelativeOffset; // the new visible portion of the parent may have tweaked coordinates |
| | 94 | } |
| | 95 | node = parent; // now see if the parent needs to be scrolled as well |
| | 96 | parent = parent.parentNode; |