Changeset 9341

Show
Ignore:
Timestamp:
06/27/07 18:06:10 (17 months ago)
Author:
sjmiles
Message:

Refactoring of html.js. Refs #3552.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • dojo/trunk/_base/html.js

    r9134 r9341  
    228228                        } 
    229229                } : function(node){ 
    230                         // FIXME: should we get using the computedStyle of the node? 
    231                         return node.style.opacity; 
     230                        return dojo.getComputedStyle(node).opacity; 
    232231                } 
    233232        ); 
     
    243242                        return opacity; 
    244243                } : function(node, opacity){ 
    245                         node.style.opacity = opacity; 
     244                        return node.style.opacity = opacity; 
    246245                } 
    247246        ); 
     
    278277        // public API 
    279278         
    280         dojo.style = function(){ 
    281                 var _a = arguments; 
    282                 var _a_l = _a.length; 
    283                 if(!_a_l){ return; } 
    284                 var node = dojo.byId(_a[0]); 
    285                 var io = ((dojo.isIE)&&(_a[1] == "opacity")); 
    286                 if(_a_l == 3){ 
    287                         return (io) ? dojo._setOpacity(node, _a[2]) : node.style[_a[1]] = _a[2]; 
    288                 } 
    289                 var s = dojo.getComputedStyle(node); 
    290                 if(_a_l == 1){ return s; } 
    291                 if(_a_l == 2){ 
    292                         return (io) ? dojo._getOpacity(node) : _toStyleValue(node, _a[1], s[_a[1]]); 
    293                 } 
     279        dojo.style = function(node /*HTMLElement*/, style/*String*/, value/*String?*/){ 
     280                var n=dojo.byId(node), args=arguments.length, op=(style=="opacity"); 
     281                if(args==3){ 
     282                        return op ? dojo._setOpacity(n, value) : n.style[style] = value; /*Number*/ 
     283                } 
     284                if (args==2 && op){ 
     285                        return dojo._getOpacity(n); 
     286                } 
     287                var s = dojo.getComputedStyle(n); 
     288                return (args == 1) ? s : _toStyleValue(n, style, s[style]); /* CSS2Properties||String||Number */ 
    294289        } 
    295290 
     
    298293        // ============================= 
    299294 
    300         dojo._getPadBounds = function(n, computedStyle){ 
     295        var gcs = dojo.getComputedStyle; 
     296         
     297        dojo._getPadExtents = function(n, computedStyle){ 
    301298                // Returns special values specifically useful  
    302299                // for node fitting. 
     
    309306                // and will use the ...box... functions instead. 
    310307                var  
    311                         s=computedStyle||dojo.getComputedStyle(n),  
     308                        s=computedStyle||gcs(n),  
    312309                        px=dojo._toPixelValue, 
    313310                        l=px(n, s.paddingLeft),  
     
    320317                }; 
    321318        } 
    322          
     319 
     320        dojo._getBorderExtents = function(n, computedStyle){ 
     321                // l/t = the sum of left/top border (respectively) 
     322                // w = the sum of the left and right border 
     323                // h = the sum of the top and bottom border 
     324                // The w/h are used for calculating boxes. 
     325                // Normally application code will not need to invoke this directly, 
     326                // and will use the ...box... functions instead. 
     327                var  
     328                        ne='none', 
     329                        px=dojo._toPixelValue,  
     330                        s=computedStyle||gcs(n),  
     331                        bl=(s.borderLeftStyle!=ne ? px(n, s.borderLeftWidth) : 0), 
     332                        bt=(s.borderTopStyle!=ne ? px(n, s.borderTopWidth) : 0); 
     333                return {  
     334                        l: bl, 
     335                        t: bt, 
     336                        w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0), 
     337                        h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0) 
     338                }; 
     339        } 
     340 
    323341        dojo._getPadBorderExtents = function(n, computedStyle){ 
    324342                // l/t = the sum of left/top padding and left/top border (respectively) 
     
    329347                // and will use the ...box... functions instead. 
    330348                var  
    331                         s=computedStyle||dojo.getComputedStyle(n),  
    332                         px=dojo._toPixelValue,  
    333                         p=dojo._getPadBounds(n, s), 
    334                         bl=(s.borderLeftStyle!='none' ? px(n, s.borderLeftWidth) : 0), 
    335                         bt=(s.borderTopStyle!='none' ? px(n, s.borderTopWidth) : 0); 
     349                        s=computedStyle||gcs(n),  
     350                        p=dojo._getPadExtents(n, s), 
     351                        b=dojo._getBorderExtents(n, s); 
    336352                return {  
    337                         l: p.l + bl, 
    338                         t: p.t + bt, 
    339                         w: p.w + bl + (s.borderRightStyle!='none' ? px(n, s.borderRightWidth) : 0), 
    340                         h: p.h + bt + (s.borderBottomStyle!='none' ? px(n, s.borderBottomWidth) : 0) 
     353                        l: p.l + b.l, 
     354                        t: p.t + b.t, 
     355                        w: p.w + b.w, 
     356                        h: p.h + b.h 
    341357                }; 
    342358        } 
     
    344360        dojo._getMarginExtents = function(n, computedStyle){ 
    345361                var  
    346                         s=computedStyle||dojo.getComputedStyle(n),  
     362                        s=computedStyle||gcs(n),  
    347363                        px=dojo._toPixelValue, 
    348364                        l=px(n, s.marginLeft), 
    349                         t=px(n, s.marginTop); 
     365                        t=px(n, s.marginTop), 
     366                        r=px(n, s.marginRight); 
     367                if (dojo.isSafari){ 
     368                        // FIXME: Safari's version of the computed right margin 
     369                        // is the space between our right edge and the right edge  
     370                        // of our offsetParent.  
     371                        // What we are looking for is the actual margin value as  
     372                        // determined by CSS. 
     373                        // Hack solution is to assume left/right margins are the same. 
     374                        r = l; 
     375                } 
    350376                return {  
    351377                        l: l, 
    352378                        t: t, 
    353                         w: l+px(n, s.marginRight), 
     379                        w: l+r, 
    354380                        h: t+px(n, s.marginBottom) 
    355381                }; 
     
    365391        // browser and browser mode. 
    366392 
    367         if(dojo.isMoz){ 
    368                 dojo._getMarginBox = function(node, computedStyle){ 
    369                         var s = computedStyle||dojo.getComputedStyle(node); 
    370                         var mb = dojo._getMarginExtents(node, s); 
    371                         // Mozilla has unexplained negative l/t offsets in some cases (e.g. positioned & parents with border) 
    372                         // the computed l/t styles are generally more correct 
    373                         return { l:(parseFloat(s.left)||node.offsetLeft) - mb.l, t:(parseFloat(s.top)||node.offsetTop) - mb.t, w: node.offsetWidth + mb.w, h: node.offsetHeight + mb.h }; 
    374                 } 
    375         } else { 
    376                 dojo._getMarginBox = function(node, computedStyle){ 
    377                         var mb = dojo._getMarginExtents(node, computedStyle); 
    378                         return { l:node.offsetLeft - mb.l, t:node.offsetTop - mb.t, w: node.offsetWidth + mb.w, h: node.offsetHeight + mb.h }; 
    379                 } 
     393        // Although it would be easier to read, there are not separate versions of  
     394        // _getMarginBox for each browser because: 
     395        // 1. the branching is not expensive 
     396        // 2. factoring the shared code wastes cycles (function call overhead) 
     397        // 3. duplicating the shared code wastes bytes 
     398         
     399        dojo._getMarginBox = function(node, computedStyle){ 
     400                var s = computedStyle||gcs(node), me = dojo._getMarginExtents(node, s); 
     401                var     l = node.offsetLeft - me.l,     t = node.offsetTop - me.t;  
     402                if(dojo.isMoz){ 
     403                        // Mozilla: 
     404                        // If offsetParent has a computed overflow != visible, the offsetLeft is decreased 
     405                        // by the parent's border. 
     406                        // We don't want to compute the parent's style, so instead we examine node's 
     407                        // computed left/top which is more stable. 
     408                        var sl = parseFloat(s.left), st = parseFloat(s.top); 
     409                        if (!isNaN(sl) && !isNaN(st)) { 
     410                                l = sl, t = st; 
     411                        } else { 
     412                                // If child's computed left/top are not parseable as a number (e.g. "auto"), we 
     413                                // have no choice but to examine the parent's computed style. 
     414                                var p = node.parentNode; 
     415                                if (p) { 
     416                                        var pcs = gcs(p); 
     417                                        if (pcs.overflow != "visible"){ 
     418                                                var be = dojo._getBorderExtents(p, pcs); 
     419                                                l += be.l, t += be.t; 
     420                                        } 
     421                                } 
     422                        } 
     423                } 
     424                // On Opera, offsetLeft includes the parent's border 
     425                else if(dojo.isOpera){ 
     426                        var p = node.parentNode; 
     427                        if(p){ 
     428                                var be = dojo._getBorderExtents(p); 
     429                                l += be.l, t += be.t; 
     430                        } 
     431                } 
     432                return {  
     433                        l: l,  
     434                        t: t,  
     435                        w: node.offsetWidth + me.w,  
     436                        h: node.offsetHeight + me.h  
     437                }; 
    380438        } 
    381439         
     
    383441                // clientWidth/Height are important since the automatically account for scrollbars 
    384442                // fallback to offsetWidth/Height for special cases (see #3378) 
    385                 var w = node.clientWidth, h, gpb; 
     443                var s=computedStyle||gcs(node), pe=dojo._getPadExtents(node, s), be=dojo._getBorderExtents(node, s), w=node.clientWidth, h; 
    386444                if (!w) { 
    387                         w = node.offsetWidth, h=node.offsetHeight, gpb= dojo._getPadBorderExtents;  
     445                        w=node.offsetWidth, h=node.offsetHeight; 
    388446                } else { 
    389                         h=node.clientHeight, gpb = dojo._getPadBounds;  
    390                 } 
    391                 var pb=gpb(node, computedStyle);  
    392                 return { l: pb.l, t: pb.t, w: w-pb.w, h: h-pb.h }; 
    393         } 
    394          
    395         dojo._setBox = function(node, l, t, w, h, u){ 
    396                 u = u || "px"; 
    397                 with(node.style){ 
    398                         if(!isNaN(l)){ left = l+u; } 
    399                         if(!isNaN(t)){ top = t+u; } 
    400                         if(w>=0){ width = w+u; } 
    401                         if(h>=0){ height = h+u; } 
    402                 } 
     447                        h=node.clientHeight, be.w = be.h = 0;  
     448                } 
     449                // On Opera, offsetLeft includes the parent's border 
     450                if(dojo.isOpera){ pe.l += be.l; pe.t += be.t; }; 
     451                return {  
     452                        l: pe.l,  
     453                        t: pe.t,  
     454                        w: w - pe.w - be.w,  
     455                        h: h - pe.h - be.h 
     456                }; 
     457        } 
     458 
     459        dojo._getBorderBox = function(node, computedStyle){ 
     460                var s=computedStyle||gcs(node), pe=dojo._getPadExtents(node, s), cb=dojo._getContentBox(node, s); 
     461                return {  
     462                        l: cb.l - pe.l,  
     463                        t: cb.t - pe.t,  
     464                        w: cb.w + pe.w,  
     465                        h: cb.h + pe.h 
     466                }; 
    403467        } 
    404468 
     
    420484        // at all in computedStyle on Mozilla. 
    421485         
    422         dojo._setContentBox = function(node, leftPx, topPx, widthPx, heightPx, computedStyle){ 
    423                 var tn = node.tagName, bb = (dojo.boxModel == "border-box")||(tn=="TABLE")||(tn=="BUTTON"); 
     486        dojo._setBox = function(node, l, t, w, h, u){ 
     487                u = u || "px"; 
     488                with(node.style){ 
     489                        if(!isNaN(l)){ left = l+u; } 
     490                        if(!isNaN(t)){ top = t+u; } 
     491                        if(w>=0){ width = w+u; } 
     492                        if(h>=0){ height = h+u; } 
     493                } 
     494        } 
     495 
     496        dojo._usesBorderBox = function(node){ 
     497                // We could test the computed style of node to see if a particular box 
     498                // has been specified, but there are details and we choose not to bother. 
     499                var n = node.tagName; 
     500                // For whatever reason, TABLE and BUTTON are always border-box by default. 
     501                // If you have assigned a different box to either one via CSS then 
     502                // box functions will break. 
     503                return (dojo.boxModel=="border-box")||(n=="TABLE")||(n=="BUTTON"); 
     504        } 
     505 
     506        dojo._setContentSize = function(node, widthPx, heightPx, computedStyle){ 
     507                var bb = dojo._usesBorderBox(node); 
    424508                if(bb){ 
    425509                        var pb = dojo._getPadBorderExtents(node, computedStyle); 
     
    427511                        if(heightPx>=0){ heightPx += pb.h; } 
    428512                } 
    429                 dojo._setBox(node, leftPx, topPx, widthPx, heightPx); 
    430         } 
    431  
    432         dojo._nilExtents = { w: 0, h: 0 }; 
     513                dojo._setBox(node, NaN, NaN, widthPx, heightPx); 
     514        } 
    433515 
    434516        dojo._setMarginBox = function(node, leftPx, topPx, widthPx, heightPx, computedStyle){ 
    435517                var s = computedStyle || dojo.getComputedStyle(node); 
    436518                // Some elements have special padding, margin, and box-model settings.  
    437                 // To use box functions with some elements you may need to set padding, margin explicitly. 
     519                // To use box functions you may need to set padding, margin explicitly. 
    438520                // Controlling box-model is harder, in a pinch you might set dojo.boxModel. 
    439                 // TABLE and BUTTON come up regularly, so we include tests for them here.  
    440                 var tn = node.tagName, pb = ((dojo.boxModel == "border-box")||(tn=="TABLE")||(tn=="BUTTON") ? dojo._nilExtents : dojo._getPadBorderExtents(node, s)); 
    441                 var mb = dojo._getMarginExtents(node, s); 
    442                 if(widthPx>=0){ 
    443                         widthPx = Math.max(widthPx - pb.w - mb.w, 0); 
    444                 } 
    445                 if(heightPx>=0){ 
    446                         heightPx = Math.max(heightPx - pb.h - mb.h, 0); 
    447                 } 
     521                var bb=dojo._usesBorderBox(node), 
     522                                pb=bb ? _nilExtents : dojo._getPadBorderExtents(node, s), 
     523                                mb=dojo._getMarginExtents(node, s); 
     524                if(widthPx>=0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0);   } 
     525                if(heightPx>=0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); } 
    448526                dojo._setBox(node, leftPx, topPx, widthPx, heightPx); 
    449527        } 
     528         
     529        var _nilExtents = { l:0, t:0, w:0, h:0 }; 
    450530 
    451531        // public API 
    452532         
    453         dojo.marginBox = function(node, boxObj){ 
    454                 node = dojo.byId(node); 
    455                 var s = dojo.getComputedStyle(node), b=boxObj; 
    456                 return !b ? dojo._getMarginBox(node, s) : dojo._setMarginBox(node, b.l, b.t, b.w, b.h, s); 
    457         } 
    458  
    459         dojo.contentBox = function(node, boxObj){ 
    460                 node = dojo.byId(node); 
    461                 var s = dojo.getComputedStyle(node), b=boxObj; 
    462                 return !b ? dojo._getContentBox(node, s) : dojo._setContentBox(node, b.l, b.t, b.w, b.h, s); 
     533        dojo.marginBox = function(node, box){ 
     534                var n=dojo.byId(node), s=gcs(n), b=box; 
     535                return !b ? dojo._getMarginBox(n, s) : dojo._setMarginBox(n, b.l, b.t, b.w, b.h, s); 
     536        } 
     537 
     538        dojo.contentBox = function(node, box){ 
     539                var n=dojo.byId(node), s=gcs(n), b=box; 
     540                return !b ? dojo._getContentBox(n, s) : dojo._setContentSize(n, b.w, b.h, s); 
    463541        } 
    464542         
     
    473551                while(node){ 
    474552                        try{ 
    475                                 if(dojo.getComputedStyle(node).position == "fixed"){ 
     553                                if(gcs(node).position == "fixed"){ 
    476554                                        return 0; 
    477555                                } 
     
    612690        // FIXME: need a setter for coords or a moveTo!! 
    613691        dojo.coords = function(node, includeScroll){ 
    614                 node = dojo.byId(node); 
    615                 var s = dojo.getComputedStyle(node); 
    616                 var mb = dojo._getMarginBox(node, s); 
    617                 var abs = dojo._abs(node, includeScroll); 
     692                var n=dojo.byId(node), s=gcs(n), mb=dojo._getMarginBox(n, s); 
     693                var abs = dojo._abs(n, includeScroll); 
    618694                mb.x = abs.x; 
    619695                mb.y = abs.y;