Ticket #6409: 6409.2.patch

File 6409.2.patch, 6.9 kB (added by doughays, 8 months ago)

new patch that handles nested scrollbars

  • _base/scroll.js

     
    1414        // It's not enough just to scroll the menu node into view if 
    1515        // node.scrollIntoView hides part of the parent's scrollbar, 
    1616        // so just manage the parent scrollbar ourselves 
     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); 
    1760        var parent = node.parentNode; 
    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; 
    2497        } 
    2598}; 
  • _Widget.js

     
    297297        }, 
    298298 
    299299        _onFocus: function(e){ 
     300                dijit.scrollIntoView(this.domNode); 
    300301                this.onFocus(); 
    301302        }, 
    302303 
  • tests/_base/test_scroll.html

     
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
     2                "http://www.w3.org/TR/html4/strict.dtd"> 
     3<html> 
     4<head> 
     5        <title>Scroll Unit Test</title> 
     6        <style type="text/css"> 
     7                @import "../../../dojo/resources/dojo.css"; 
     8                @import "../css/dijitTests.css"; 
     9        </style> 
     10        <script type="text/javascript" src="../../../dojo/dojo.js" 
     11                djConfig="isDebug: true"></script> 
     12        <script type="text/javascript" src="../_testCommon.js"></script> 
     13 
     14        <script type="text/javascript"> 
     15                dojo.require("doh.runner"); 
     16                dojo.require("dijit._base.scroll"); 
     17 
     18                function scrollit(){ 
     19                        dijit.scrollIntoView('q1'); 
     20                } 
     21 
     22                dojo.addOnLoad(function(){ 
     23                        doh.register("dijit._base.scroll", 
     24                        [ 
     25                                function scrollIntoView(){ 
     26                                        dojo.global.scrollTo(0,0); 
     27                                        var s1 = dojo.byId('s1'); 
     28                                        s1.scrollTop = s1.scrollLeft = 0; 
     29                                        scrollit(); 
     30                                        doh.is(s1.scrollLeft, 85); 
     31                                        doh.is(s1.scrollTop, 111); 
     32                                        dojo.global.scrollTo(0,2000); 
     33                                } 
     34                        ]); 
     35                        doh.run(); 
     36                }); 
     37        </script> 
     38</head> 
     39<body onclick="scrollit()"> 
     40        <h1><center>scrollIntoView test: shows NO blue background.  Click document body to re-scroll</center></h1> 
     41        <img src="../../../dojo/resources/blank.gif" style="height:888px;width:1px;display:block;background-color:white;"> 
     42        <div id="s1" style="width:650px;height:600px;overflow:scroll;background-color:blue;border:0px solid white;margin:0px;padding:0px;border-width:45px 35px 15px 25px;" 
     43                ><img src="../../../dojo/resources/blank.gif" style="height:111px;width:1px;display:block;" 
     44                ><nobr id="p1" style="display:block;border:0px;padding:0px;margin:0px;" 
     45                        ><img id="c1" src="../../../dojo/resources/blank.gif" style="height:1px;width:85px;display:inline;" 
     46                        ><img id="q1" src="../../../dojo/resources/blank.gif" style="background-color:white;width:650px;height:600px;display:inline;overflow:visible;" 
     47                        ><img id="c2" src="../../../dojo/resources/blank.gif" style="height:1px;width:85px;display:inline;" 
     48                ></nobr 
     49                ><img src="../../../dojo/resources/blank.gif" style="height:222px;width:1px;display:block;" 
     50        ></div> 
     51        <img src="../../../dojo/resources/blank.gif" style="height:555px;width:1px;display:block;"> 
     52</body> 
     53</html>