dojo.provide("dojo.browser.layout"); (function() { // // I hate to do this but the byte/cycle savings are hard to pass up. // // Is there any cost to making the various functions declared here // closures under this anonymous function? // var dh = dojo.html; var drh = dojo.render.html; // I don't greatly like returning objects, but I'm not convinced that making // multiple calls is less costly in time or space. // Another tack might be to pass in an 'extents' object to be filled in, but // I also don't believe that saves much (anything?) dh.getPadBorderBounds = function(node, computedStyle) { // This values returned from this function are perhaps non-intuitve, // but they are specifically useful for fitting nodes. // l, t = the top and left edges as determined by padding // Assuming 'node' has position, then for child nodes, these l/t are the origin. // w = the total of the right padding and left and right border // h = the total of the bottom padding and top and bottom border // The w/h are used for calculating boxes. // Normally application code will not need to invoke this directly, // and will use the ...box... functions instead. var s = computedStyle || this.getComputedStyle(node), px = dh.getPixelizer(node); var l = px(s.paddingLeft), t = px(s.paddingTop); var bw = (s.borderLeftStyle != 'none' ? px(s.borderLeftWidth) : 0) + (s.borderRightStyle != 'none' ? px(s.borderRightWidth) : 0); var bh = (s.borderTopStyle != 'none' ? px(s.borderTopWidth) : 0) + (s.borderBottomStyle != 'none' ? px(s.borderBottomWidth) : 0); return { l: l, t: t, w: l + bw + px(s.paddingRight), h: t + bh + px(s.paddingBottom) }; } dh.getMarginExtents = function(node, computedStyle) { var px = dh.getPixelizer(node); var s = computedStyle || this.getComputedStyle(node); return { w: px(s.marginLeft) + px(s.marginRight), h: px(s.marginTop) + px(s.marginBottom) }; } // Box getters work in any box context because offsetWidth is invariant wrt box context // // They do *not* work for display: inline objects that have padding styles // because the user agent ignores padding (it's bogus styling in any case) // // Be careful with IMGs because they are inline or block depending on // browser and browser mode. dh.getMarginBox = function(node, computedStyle) { var mb = dh.getMarginExtents(node, computedStyle); return {l:0, t:0, w: node.offsetWidth + mb.w, h: node.offsetHeight + mb.h }; } dh.getContentBox = function(node, computedStyle) { var pb = dh.getPadBorderBounds(node, computedStyle); return {l: pb.l, t: pb.t, w: node.offsetWidth - pb.w, h: node.offsetHeight- pb.h }; } // Box setters depend on box context because interpretation of width/height styles // vary wrt box context. // // The value of dojo.render.html.box is used to determine box context. // - For IE dojo.render.html.box is auto-detected (quirks vs standards mode) // - For all other browsers, content-box is assumed by default. Per-node box setting // via CSS is not supported. // - dojo.render.html.box can be set directly to change behavior. // // Again, beware of display: inline objects that have padding styles // because the user agent ignores padding (it's a bogus setup anyway) // // Be careful with IMGs because they are inline or block depending on // browser and browser mode. dh.setContentBox = function(node, leftPx, topPx, widthPx, heightPx, computedStyle) { if (drh.box == dh.box.BORDER_BOX) { var pb = dh.getPadBorderBounds(node, computedStyle); if (widthPx>=0) widthPx += pb.w; if (heightPx>=0) heightPx += pb.h; } // factoring this section out from these two functions // actually costs more bytes than it saves // unless we decide to use a closure to reduce instances of dojo.html with (node.style) { if (leftPx>=0) left = leftPx + 'px'; if (topPx>=0) top = topPx + 'px'; if (widthPx>=0) width = widthPx + 'px'; if (heightPx>=0) height = heightPx + 'px'; } } dh._nilExtents = { w: 0, h: 0 }; dh.setMarginBox = function(node, leftPx, topPx, widthPx, heightPx, computedStyle) { var s = computedStyle || dh.getComputedStyle(node); var pb = (drh.box == dh.box.BORDER_BOX ? dh._nilExtents : dh.getPadBorderBounds(node, s)); var mb = dh.getMarginExtents(node, s); with (node.style) { if (leftPx>=0) left = leftPx + 'px'; if (topPx>=0) top = topPx + 'px'; if (widthPx>=0) width = Math.max(widthPx - pb.w - mb.w, 0) + 'px'; if (heightPx>=0) height = Math.max(heightPx - pb.h - mb.h, 0) + 'px'; } } })();