Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(position): add new positioning service
Browse files Browse the repository at this point in the history
  • Loading branch information
pkozlowski-opensource committed Apr 15, 2013
1 parent 9e6e969 commit ab0bce4
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/position/position.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
angular.module('ui.bootstrap.position', [])

/**
* A set of utility methods that can be use to retrieve position of DOM elements.
* It is meant to be used where we need to absolute-position DOM elements in
* relation to other, existing elements (this is the case for tooltips, popovers,
* typeahead suggestions etc.).
*/
.factory('$position', ['$document', '$window', function ($document, $window) {

/**
* returns the closest, non-statically positioned parentOffset of a given element
* @param element
*/
var parentOffsetEl = function (element) {
var docDomEl = $document[0];
var offsetParent = element.offsetParent || docDomEl;
while (offsetParent && (offsetParent !== docDomEl && (angular.element(offsetParent).css("position") || 'static' ) === 'static' )) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || docDomEl;
};

return {
/**
* Provides read-only equivalent of jQuery's position function:
* http://api.jquery.com/position/
*/
position: function (element) {
var elBCR = this.offset(element);
var offsetParentBCR = { top: 0, left: 0 };

var offsetParentEl = parentOffsetEl(element[0]);
if (offsetParentEl != $document[0]) {
offsetParentBCR = this.offset(angular.element(offsetParentEl));
offsetParentBCR.top += offsetParentEl.clientTop;
offsetParentBCR.left += offsetParentEl.clientLeft;
}

return {
width: element.prop('offsetWidth'),
height: element.prop('offsetHeight'),
top: elBCR.top - offsetParentBCR.top,
left: elBCR.left - offsetParentBCR.left
};
},

/**
* Provides read-only equivalent of jQuery's offset function:
* http://api.jquery.com/offset/
*/
offset: function (element) {
var boundingClientRect = element[0].getBoundingClientRect();
return {
width: element.prop('offsetWidth'),
height: element.prop('offsetHeight'),
top: boundingClientRect.top + $window.pageYOffset,
left: boundingClientRect.left + $window.pageXOffset
};
}
};
}]);
107 changes: 107 additions & 0 deletions src/position/test/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en" ng-app="position">
<head>
<meta charset="utf-8">
<script src="../../../misc/test-lib/angular.js"></script>
<script src="../position.js"></script>
<style type="text/css">
.container {
border: 1px solid red;
}

.content {
border: 5px solid #808080;
background-color: dodgerblue;
width: 200px;
}

.positioned {
border: 5px solid #808080;
background-color: green;
position: absolute;
}
</style>
<script type="text/javascript">
angular.module('position', ['ui.bootstrap.position']).directive('position', function ($compile, $position) {
return {
link: function (scope, element, attrs) {

var positionedEl = angular.element('<div class="positioned">Positioned</div>');
var elPosition = $position.position(element);
elPosition.left += elPosition.width;

positionedEl.css({left: elPosition.left + 'px', top: elPosition.top + 'px'});
element.after($compile(positionedEl)(scope));
}
};
});
</script>
</head>
<body class="container">
<h3>Within body</h3>

<div class="content" position>Content</div>

<h3>Within statically positioned DIV</h3>

<div class="container">
<div class="content" position>Content</div>
</div>

<h3>Within relative-positioned DIV</h3>

<div style="position: relative; left: 200px" class="container">
<div class="content" position>Content</div>
</div>

<h3>Within absolute-positioned DIV</h3>

<div style="position: absolute; left: 400px" class="container">
<div class="content" position>Content</div>
</div>

<h3>Next to a float element</h3>

<div class="container">
<div class="content" style="float: right" position>Content</div>
</div>

<h3>Within a table</h3>
<table class="container">
<tr>
<td>Some other content</td>
<td>
<div class="content" position>Content</div>
</td>
</tr>
</table>

<h3>Within a table that is inside a relative-positioned DIV</h3>

<div style="position: relative; left: 200px" class="container">
<table class="container">
<tr>
<td>Some other content</td>
<td>
<div class="content" position>Content</div>
</td>
</tr>
</table>
</div>

<h3>Inside looong text</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non velit nulla. Suspendisse sit amet tempus diam. Sed at ultricies neque. Suspendisse id felis a sem placerat ornare. Donec auctor, purus at molestie tempor, arcu enim molestie lacus, ac imperdiet massa urna eu massa. Praesent velit tellus, scelerisque a fermentum ut, ornare in diam. Phasellus egestas molestie feugiat. Vivamus sit amet viverra metus.</p>
<p>Etiam ultricies odio commodo erat ullamcorper sodales. Nullam ac dui ac libero dictum mollis. Quisque convallis adipiscing facilisis. In nec nisi velit, id auctor lectus. Cras interdum urna non felis lacinia vulputate. Integer dignissim, mi aliquam gravida auctor, massa odio cursus lorem, eu ultrices eros nisl tempus diam. Maecenas tristique pellentesque nisi sed adipiscing. Aenean hendrerit sapien quis arcu lobortis vitae pulvinar ante volutpat. Morbi consectetur erat eu lacus facilisis eu ullamcorper orci euismod. Quisque diam dui, interdum in suscipit et, fringilla non justo. Pellentesque non nibh odio. Proin sit amet massa sem.</p>
<p>Nam in urna erat, at congue nisi. Donec eu tellus lorem, sed facilisis tellus. Aliquam suscipit faucibus ipsum, at hendrerit metus interdum at. Integer et eros ac lacus vulputate sagittis quis quis erat. Suspendisse consectetur vehicula purus vitae imperdiet. Suspendisse in augue magna, quis imperdiet enim. Nullam non diam ac erat auctor bibendum. Praesent ante mauris, egestas sit amet molestie sed, tristique at lorem. Nam at mi ac nisl venenatis semper nec eget mi. Pellentesque a lectus ac leo feugiat suscipit. Quisque tristique dui nec urna placerat a viverra mi iaculis. Ut et tellus et turpis sagittis iaculis nec eu magna. Sed quis nunc non arcu tincidunt ultricies viverra id mauris.</p>
<p>Curabitur luctus rutrum ultricies. Aenean ut rutrum orci. Sed molestie lorem in leo cursus id feugiat nisi scelerisque. Maecenas pulvinar neque nec lacus feugiat dictum. Donec viverra felis nec nisi mollis feugiat. Phasellus vehicula, ligula at mattis porttitor, sapien urna hendrerit quam, at fringilla nisl quam vel elit. In eu lacus ligula. Praesent eget gravida nisl. Suspendisse velit diam, pellentesque a tempus quis, vestibulum vel leo.</p>
<p>Maecenas feugiat ultrices laoreet. Sed congue posuere diam ac faucibus. Pellentesque eget leo ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed nec quam eu tellus sagittis cursus a sit amet eros. Mauris sit amet orci at orci vulputate commodo ut ut nunc. Etiam sagittis erat ut nisi ultricies feugiat. Morbi sed eros nisi. Cras vitae augue in risus aliquet commodo non id est.</p>
<div class="content" position>HERE</div>
<p>Maecenas laoreet nisi pretium elit bibendum eget tempor nunc aliquet. Vivamus interdum nisi sit amet tortor fermentum congue. Suspendisse at posuere erat. Aliquam hendrerit ultricies nunc non adipiscing. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis molestie viverra nulla a aliquet. Nullam non eros vel sem vehicula suscipit. Ut sit amet arcu ac tortor dignissim viverra in a ligula.</p>

<div style="position: fixed; bottom: 0px" class="container">
<h3>Within fixed div</h3>
<div class="content" position>Content</div>
</div>

</body>
</html>

0 comments on commit ab0bce4

Please sign in to comment.