Skip to content

Commit

Permalink
Switched from less generic and heinously long method name to enyo.dom…
Browse files Browse the repository at this point in the history
….calcNodePosition, which also allows calculating relative to arbitrary parent nodes

Updated tests to use new method, and test node-relative measurements
Enyo-DCO-1.1-Signed-off-by: Ian Beck <ian@onecrayon.com>
  • Loading branch information
onecrayon committed Dec 15, 2012
1 parent 53d4988 commit e956c5e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
24 changes: 16 additions & 8 deletions source/dom/dom.js
Expand Up @@ -139,20 +139,28 @@ enyo.dom = {
calcMarginExtents: function(inNode) {
return this.calcBoxExtents(inNode, "margin");
},
//* Returns an object like `{top: 0, left: 0, bottom: 100, right: 100, height: 10, width: 10}` that represents the object's position within the viewport. Negative values mean part of the object is not visible.
calcViewportPositionForNode: function(inNode) {
//* Returns an object like `{top: 0, left: 0, bottom: 100, right: 100, height: 10, width: 10}` that represents the object's position relative to `relativeToNode` (suitable for absolute positioning within that parent node). Negative values mean part of the object is not visible. If you leave `relativeToNode` undefined (or it is not a parent element), then the position will be relative to the viewport and suitable for absolute positioning in a floating layer.
calcNodePosition: function(inNode, relativeToNode) {
// Parse upward and grab our positioning relative to the viewport
var top = 0,
left = 0,
node = inNode,
width = node.offsetWidth,
height = node.offsetHeight,
docHeight = (document.body.parentNode.offsetHeight > this.getWindowHeight() ? this.getWindowHeight() - document.body.parentNode.scrollTop : document.body.parentNode.offsetHeight),
docWidth = (document.body.parentNode.offsetWidth > this.getWindowWidth() ? this.getWindowWidth() - document.body.parentNode.scrollLeft : document.body.parentNode.offsetWidth),
transformProp = enyo.dom.getStyleTransformProp(),
xregex = /translateX\((-?\d+)px\)/i,
yregex = /translateY\((-?\d+)px\)/i,
borderLeft = 0, borderTop = 0;
borderLeft = 0, borderTop = 0,
totalHeight = 0, totalWidth = 0;

if (relativeToNode) {
totalHeight = relativeToNode.offsetHeight;
totalWidth = relativeToNode.offsetWidth;
} else {
totalHeight = (document.body.parentNode.offsetHeight > this.getWindowHeight() ? this.getWindowHeight() - document.body.parentNode.scrollTop : document.body.parentNode.offsetHeight);
totalWidth = (document.body.parentNode.offsetWidth > this.getWindowWidth() ? this.getWindowWidth() - document.body.parentNode.scrollLeft : document.body.parentNode.offsetWidth);
}

if (node.offsetParent) {
do {
left += node.offsetLeft - (node.offsetParent ? node.offsetParent.scrollLeft : 0);
Expand Down Expand Up @@ -184,13 +192,13 @@ enyo.dom = {
top += borderTop;
}
}
} while ((node = node.offsetParent));
} while ((node = node.offsetParent) && node !== relativeToNode);
}
return {
'top': top,
'left': left,
'bottom': docHeight - top - height,
'right': docWidth - left - width,
'bottom': totalHeight - top - height,
'right': totalWidth - left - width,
'height': height,
'width': width
};
Expand Down
30 changes: 27 additions & 3 deletions tools/test/core/tests/ViewportPositioningTest.js
Expand Up @@ -22,7 +22,7 @@ enyo.kind({
var k = new K();
k.renderInto(div);

var p = enyo.dom.calcViewportPositionForNode(k.hasNode()),
var p = enyo.dom.calcNodePosition(k.hasNode()),
// Bottom and right require calculating viewport size
fromBottom = (document.body.parentNode.offsetHeight > enyo.dom.getWindowHeight() ? enyo.dom.getWindowHeight() - document.body.parentNode.scrollTop : document.body.parentNode.offsetHeight) - 20,
fromRight = (document.body.parentNode.offsetWidth > enyo.dom.getWindowWidth() ? enyo.dom.getWindowWidth() - document.body.parentNode.scrollLeft : document.body.parentNode.offsetWidth) - 20;
Expand All @@ -47,8 +47,8 @@ enyo.kind({

// Now test measuring the element when a parent has a border
div.style.border = "1px solid transparent";
k.hasNode().style.border = "1px solid transparent"
p = enyo.dom.calcViewportPositionForNode(k.hasNode()),
k.hasNode().style.border = "1px solid transparent";
p = enyo.dom.calcNodePosition(k.hasNode()),
// We don't count the right border on the element itself because that is taken into account automatically by the element's width measurement
fromBottom -= 3,
fromRight -= 3;
Expand All @@ -70,6 +70,30 @@ enyo.kind({
if (p.height !== 12) {
this.log('height with border failed with value: ' + p.height + ' (should be 12)');
}

// And finally, test positioning relative to another node
p = enyo.dom.calcNodePosition(k.hasNode(), div),
// Reset to div size - node height
fromBottom = div.offsetHeight - 22,
fromRight = div.offsetWidth - 22;
if (p.top !== 10) {
this.log('top relative to div failed with value: ' + p.top + ' (should be 10)');
}
if (p.left !== 10) {
this.log('left relative to div failed with value: ' + p.left + ' (should be 10)');
}
if (p.bottom !== fromBottom) {
this.log('bottom relative to div failed with value: ' + p.bottom + ' (should be ' + fromBottom + ')');
}
if (p.right !== fromRight) {
this.log('right relative to div failed with value: ' + p.right + ' (should be ' + fromRight + ')');
}
if (p.width !== 12) {
this.log('width relative to div failed with value: ' + p.width + ' (should be 12)');
}
if (p.height !== 12) {
this.log('height relative to div failed with value: ' + p.height + ' (should be 12)');
}

// Clean up
k.destroy();
Expand Down

0 comments on commit e956c5e

Please sign in to comment.