blob: 4c2f8c42c7c03efad16d2f27f906beee2d254133 [file] [log] [blame]
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.layout");
dojo.require("dojo.html.common");
dojo.require("dojo.html.style");
dojo.require("dojo.html.display");
dojo.html.sumAncestorProperties = function (node, prop) {
node = dojo.byId(node);
if (!node) {
return 0;
}
var retVal = 0;
while (node) {
if (dojo.html.getComputedStyle(node, "position") == "fixed") {
return 0;
}
var val = node[prop];
if (val) {
retVal += val - 0;
if (node == dojo.body()) {
break;
}
}
node = node.parentNode;
}
return retVal;
};
dojo.html.setStyleAttributes = function (node, attributes) {
node = dojo.byId(node);
var splittedAttribs = attributes.replace(/(;)?\s*$/, "").split(";");
for (var i = 0; i < splittedAttribs.length; i++) {
var nameValue = splittedAttribs[i].split(":");
var name = nameValue[0].replace(/\s*$/, "").replace(/^\s*/, "").toLowerCase();
var value = nameValue[1].replace(/\s*$/, "").replace(/^\s*/, "");
switch (name) {
case "opacity":
dojo.html.setOpacity(node, value);
break;
case "content-height":
dojo.html.setContentBox(node, {height:value});
break;
case "content-width":
dojo.html.setContentBox(node, {width:value});
break;
case "outer-height":
dojo.html.setMarginBox(node, {height:value});
break;
case "outer-width":
dojo.html.setMarginBox(node, {width:value});
break;
default:
node.style[dojo.html.toCamelCase(name)] = value;
}
}
};
dojo.html.boxSizing = {MARGIN_BOX:"margin-box", BORDER_BOX:"border-box", PADDING_BOX:"padding-box", CONTENT_BOX:"content-box"};
dojo.html.getAbsolutePosition = dojo.html.abs = function (node, includeScroll, boxType) {
node = dojo.byId(node, node.ownerDocument);
var ret = {x:0, y:0};
var bs = dojo.html.boxSizing;
if (!boxType) {
boxType = bs.CONTENT_BOX;
}
var nativeBoxType = 2;
var targetBoxType;
switch (boxType) {
case bs.MARGIN_BOX:
targetBoxType = 3;
break;
case bs.BORDER_BOX:
targetBoxType = 2;
break;
case bs.PADDING_BOX:
default:
targetBoxType = 1;
break;
case bs.CONTENT_BOX:
targetBoxType = 0;
break;
}
var h = dojo.render.html;
var db = document["body"] || document["documentElement"];
if (h.ie) {
with (node.getBoundingClientRect()) {
ret.x = left - 2;
ret.y = top - 2;
}
} else {
if (document.getBoxObjectFor) {
nativeBoxType = 1;
try {
var bo = document.getBoxObjectFor(node);
ret.x = bo.x - dojo.html.sumAncestorProperties(node, "scrollLeft");
ret.y = bo.y - dojo.html.sumAncestorProperties(node, "scrollTop");
}
catch (e) {
}
} else {
if (node["offsetParent"]) {
var endNode;
if ((h.safari) && (node.style.getPropertyValue("position") == "absolute") && (node.parentNode == db)) {
endNode = db;
} else {
endNode = db.parentNode;
}
if (node.parentNode != db) {
var nd = node;
if (dojo.render.html.opera) {
nd = db;
}
ret.x -= dojo.html.sumAncestorProperties(nd, "scrollLeft");
ret.y -= dojo.html.sumAncestorProperties(nd, "scrollTop");
}
var curnode = node;
do {
var n = curnode["offsetLeft"];
if (!h.opera || n > 0) {
ret.x += isNaN(n) ? 0 : n;
}
var m = curnode["offsetTop"];
ret.y += isNaN(m) ? 0 : m;
curnode = curnode.offsetParent;
} while ((curnode != endNode) && (curnode != null));
} else {
if (node["x"] && node["y"]) {
ret.x += isNaN(node.x) ? 0 : node.x;
ret.y += isNaN(node.y) ? 0 : node.y;
}
}
}
}
if (includeScroll) {
var scroll = dojo.html.getScroll();
ret.y += scroll.top;
ret.x += scroll.left;
}
var extentFuncArray = [dojo.html.getPaddingExtent, dojo.html.getBorderExtent, dojo.html.getMarginExtent];
if (nativeBoxType > targetBoxType) {
for (var i = targetBoxType; i < nativeBoxType; ++i) {
ret.y += extentFuncArray[i](node, "top");
ret.x += extentFuncArray[i](node, "left");
}
} else {
if (nativeBoxType < targetBoxType) {
for (var i = targetBoxType; i > nativeBoxType; --i) {
ret.y -= extentFuncArray[i - 1](node, "top");
ret.x -= extentFuncArray[i - 1](node, "left");
}
}
}
ret.top = ret.y;
ret.left = ret.x;
return ret;
};
dojo.html.isPositionAbsolute = function (node) {
return (dojo.html.getComputedStyle(node, "position") == "absolute");
};
dojo.html._sumPixelValues = function (node, selectors, autoIsZero) {
var total = 0;
for (var x = 0; x < selectors.length; x++) {
total += dojo.html.getPixelValue(node, selectors[x], autoIsZero);
}
return total;
};
dojo.html.getMargin = function (node) {
return {width:dojo.html._sumPixelValues(node, ["margin-left", "margin-right"], (dojo.html.getComputedStyle(node, "position") == "absolute")), height:dojo.html._sumPixelValues(node, ["margin-top", "margin-bottom"], (dojo.html.getComputedStyle(node, "position") == "absolute"))};
};
dojo.html.getBorder = function (node) {
return {width:dojo.html.getBorderExtent(node, "left") + dojo.html.getBorderExtent(node, "right"), height:dojo.html.getBorderExtent(node, "top") + dojo.html.getBorderExtent(node, "bottom")};
};
dojo.html.getBorderExtent = function (node, side) {
return (dojo.html.getStyle(node, "border-" + side + "-style") == "none" ? 0 : dojo.html.getPixelValue(node, "border-" + side + "-width"));
};
dojo.html.getMarginExtent = function (node, side) {
return dojo.html._sumPixelValues(node, ["margin-" + side], dojo.html.isPositionAbsolute(node));
};
dojo.html.getPaddingExtent = function (node, side) {
return dojo.html._sumPixelValues(node, ["padding-" + side], true);
};
dojo.html.getPadding = function (node) {
return {width:dojo.html._sumPixelValues(node, ["padding-left", "padding-right"], true), height:dojo.html._sumPixelValues(node, ["padding-top", "padding-bottom"], true)};
};
dojo.html.getPadBorder = function (node) {
var pad = dojo.html.getPadding(node);
var border = dojo.html.getBorder(node);
return {width:pad.width + border.width, height:pad.height + border.height};
};
dojo.html.getBoxSizing = function (node) {
var h = dojo.render.html;
var bs = dojo.html.boxSizing;
if (((h.ie) || (h.opera)) && node.nodeName.toLowerCase() != "img") {
var cm = document["compatMode"];
if ((cm == "BackCompat") || (cm == "QuirksMode")) {
return bs.BORDER_BOX;
} else {
return bs.CONTENT_BOX;
}
} else {
if (arguments.length == 0) {
node = document.documentElement;
}
var sizing;
if (!h.ie) {
sizing = dojo.html.getStyle(node, "-moz-box-sizing");
if (!sizing) {
sizing = dojo.html.getStyle(node, "box-sizing");
}
}
return (sizing ? sizing : bs.CONTENT_BOX);
}
};
dojo.html.isBorderBox = function (node) {
return (dojo.html.getBoxSizing(node) == dojo.html.boxSizing.BORDER_BOX);
};
dojo.html.getBorderBox = function (node) {
node = dojo.byId(node);
return {width:node.offsetWidth, height:node.offsetHeight};
};
dojo.html.getPaddingBox = function (node) {
var box = dojo.html.getBorderBox(node);
var border = dojo.html.getBorder(node);
return {width:box.width - border.width, height:box.height - border.height};
};
dojo.html.getContentBox = function (node) {
node = dojo.byId(node);
var padborder = dojo.html.getPadBorder(node);
return {width:node.offsetWidth - padborder.width, height:node.offsetHeight - padborder.height};
};
dojo.html.setContentBox = function (node, args) {
node = dojo.byId(node);
var width = 0;
var height = 0;
var isbb = dojo.html.isBorderBox(node);
var padborder = (isbb ? dojo.html.getPadBorder(node) : {width:0, height:0});
var ret = {};
if (typeof args.width != "undefined") {
width = args.width + padborder.width;
ret.width = dojo.html.setPositivePixelValue(node, "width", width);
}
if (typeof args.height != "undefined") {
height = args.height + padborder.height;
ret.height = dojo.html.setPositivePixelValue(node, "height", height);
}
return ret;
};
dojo.html.getMarginBox = function (node) {
var borderbox = dojo.html.getBorderBox(node);
var margin = dojo.html.getMargin(node);
return {width:borderbox.width + margin.width, height:borderbox.height + margin.height};
};
dojo.html.setMarginBox = function (node, args) {
node = dojo.byId(node);
var width = 0;
var height = 0;
var isbb = dojo.html.isBorderBox(node);
var padborder = (!isbb ? dojo.html.getPadBorder(node) : {width:0, height:0});
var margin = dojo.html.getMargin(node);
var ret = {};
if (typeof args.width != "undefined") {
width = args.width - padborder.width;
width -= margin.width;
ret.width = dojo.html.setPositivePixelValue(node, "width", width);
}
if (typeof args.height != "undefined") {
height = args.height - padborder.height;
height -= margin.height;
ret.height = dojo.html.setPositivePixelValue(node, "height", height);
}
return ret;
};
dojo.html.getElementBox = function (node, type) {
var bs = dojo.html.boxSizing;
switch (type) {
case bs.MARGIN_BOX:
return dojo.html.getMarginBox(node);
case bs.BORDER_BOX:
return dojo.html.getBorderBox(node);
case bs.PADDING_BOX:
return dojo.html.getPaddingBox(node);
case bs.CONTENT_BOX:
default:
return dojo.html.getContentBox(node);
}
};
dojo.html.toCoordinateObject = dojo.html.toCoordinateArray = function (coords, includeScroll, boxtype) {
if (coords instanceof Array || typeof coords == "array") {
dojo.deprecated("dojo.html.toCoordinateArray", "use dojo.html.toCoordinateObject({left: , top: , width: , height: }) instead", "0.5");
while (coords.length < 4) {
coords.push(0);
}
while (coords.length > 4) {
coords.pop();
}
var ret = {left:coords[0], top:coords[1], width:coords[2], height:coords[3]};
} else {
if (!coords.nodeType && !(coords instanceof String || typeof coords == "string") && ("width" in coords || "height" in coords || "left" in coords || "x" in coords || "top" in coords || "y" in coords)) {
var ret = {left:coords.left || coords.x || 0, top:coords.top || coords.y || 0, width:coords.width || 0, height:coords.height || 0};
} else {
var node = dojo.byId(coords);
var pos = dojo.html.abs(node, includeScroll, boxtype);
var marginbox = dojo.html.getMarginBox(node);
var ret = {left:pos.left, top:pos.top, width:marginbox.width, height:marginbox.height};
}
}
ret.x = ret.left;
ret.y = ret.top;
return ret;
};
dojo.html.setMarginBoxWidth = dojo.html.setOuterWidth = function (node, width) {
return dojo.html._callDeprecated("setMarginBoxWidth", "setMarginBox", arguments, "width");
};
dojo.html.setMarginBoxHeight = dojo.html.setOuterHeight = function () {
return dojo.html._callDeprecated("setMarginBoxHeight", "setMarginBox", arguments, "height");
};
dojo.html.getMarginBoxWidth = dojo.html.getOuterWidth = function () {
return dojo.html._callDeprecated("getMarginBoxWidth", "getMarginBox", arguments, null, "width");
};
dojo.html.getMarginBoxHeight = dojo.html.getOuterHeight = function () {
return dojo.html._callDeprecated("getMarginBoxHeight", "getMarginBox", arguments, null, "height");
};
dojo.html.getTotalOffset = function (node, type, includeScroll) {
return dojo.html._callDeprecated("getTotalOffset", "getAbsolutePosition", arguments, null, type);
};
dojo.html.getAbsoluteX = function (node, includeScroll) {
return dojo.html._callDeprecated("getAbsoluteX", "getAbsolutePosition", arguments, null, "x");
};
dojo.html.getAbsoluteY = function (node, includeScroll) {
return dojo.html._callDeprecated("getAbsoluteY", "getAbsolutePosition", arguments, null, "y");
};
dojo.html.totalOffsetLeft = function (node, includeScroll) {
return dojo.html._callDeprecated("totalOffsetLeft", "getAbsolutePosition", arguments, null, "left");
};
dojo.html.totalOffsetTop = function (node, includeScroll) {
return dojo.html._callDeprecated("totalOffsetTop", "getAbsolutePosition", arguments, null, "top");
};
dojo.html.getMarginWidth = function (node) {
return dojo.html._callDeprecated("getMarginWidth", "getMargin", arguments, null, "width");
};
dojo.html.getMarginHeight = function (node) {
return dojo.html._callDeprecated("getMarginHeight", "getMargin", arguments, null, "height");
};
dojo.html.getBorderWidth = function (node) {
return dojo.html._callDeprecated("getBorderWidth", "getBorder", arguments, null, "width");
};
dojo.html.getBorderHeight = function (node) {
return dojo.html._callDeprecated("getBorderHeight", "getBorder", arguments, null, "height");
};
dojo.html.getPaddingWidth = function (node) {
return dojo.html._callDeprecated("getPaddingWidth", "getPadding", arguments, null, "width");
};
dojo.html.getPaddingHeight = function (node) {
return dojo.html._callDeprecated("getPaddingHeight", "getPadding", arguments, null, "height");
};
dojo.html.getPadBorderWidth = function (node) {
return dojo.html._callDeprecated("getPadBorderWidth", "getPadBorder", arguments, null, "width");
};
dojo.html.getPadBorderHeight = function (node) {
return dojo.html._callDeprecated("getPadBorderHeight", "getPadBorder", arguments, null, "height");
};
dojo.html.getBorderBoxWidth = dojo.html.getInnerWidth = function () {
return dojo.html._callDeprecated("getBorderBoxWidth", "getBorderBox", arguments, null, "width");
};
dojo.html.getBorderBoxHeight = dojo.html.getInnerHeight = function () {
return dojo.html._callDeprecated("getBorderBoxHeight", "getBorderBox", arguments, null, "height");
};
dojo.html.getContentBoxWidth = dojo.html.getContentWidth = function () {
return dojo.html._callDeprecated("getContentBoxWidth", "getContentBox", arguments, null, "width");
};
dojo.html.getContentBoxHeight = dojo.html.getContentHeight = function () {
return dojo.html._callDeprecated("getContentBoxHeight", "getContentBox", arguments, null, "height");
};
dojo.html.setContentBoxWidth = dojo.html.setContentWidth = function (node, width) {
return dojo.html._callDeprecated("setContentBoxWidth", "setContentBox", arguments, "width");
};
dojo.html.setContentBoxHeight = dojo.html.setContentHeight = function (node, height) {
return dojo.html._callDeprecated("setContentBoxHeight", "setContentBox", arguments, "height");
};