diff --git a/src/position/docs/readme.md b/src/position/docs/readme.md index fe0b68a2b4..58f8d9dad1 100644 --- a/src/position/docs/readme.md +++ b/src/position/docs/readme.md @@ -54,8 +54,26 @@ Calculates the browser scrollbar width and caches the result for future calls. * _(Type: `number`)_ - The width of the browser scrollbar. +#### isScrollable(element, includeHidden) + +Determines if an element is scrollable. + +##### parameters + +* `element` + _(Type: `element`)_ - + The element to check. + +* `includeHidden` + _(Type: `boolean`, Default: `false`, optional)_ - Should scroll style of 'hidden' be considered. + +##### returns + +* _(Type: `boolean`)_ - + Whether the element is scrollable. + #### scrollParent(element, includeHidden) - + Gets the closest scrollable ancestor. Concept from the jQueryUI [scrollParent.js](https://github.com/jquery/jquery-ui/blob/master/ui/scroll-parent.js). ##### parameters @@ -91,21 +109,21 @@ An object with the following properties: * `width` _(Type: `number`)_ - The width of the element. - + * `height` _(Type: `number`)_ - The height of the element. - + * `top` _(Type: `number`)_ - Distance to top edge of offset parent. - + * `left` _(Type: `number`)_ - Distance to left edge of offset parent. #### offset(element) - + A read-only equivalent of jQuery's [offset](http://api.jquery.com/offset/) function, distance to viewport. ##### parameters @@ -121,21 +139,21 @@ An object with the following properties: * `width` _(Type: `number`)_ - The width of the element. - + * `height` _(Type: `number`)_ - The height of the element. - + * `top` _(Type: `number`)_ - Distance to top edge of the viewport. - + * `left` _(Type: `number`)_ - Distance to left edge of the viewport. - + #### viewportOffset(element, useDocument, includePadding) - + Gets the elements available space relative to the closest scrollable ancestor. Accounts for padding, border, and scrollbar width. Right and bottom dimensions represent the distance to the respective edge of the viewport element, not the top and left edge. If the element edge extends beyond the viewport, a negative value will be reported. @@ -145,11 +163,11 @@ If the element edge extends beyond the viewport, a negative value will be report * `element` _(Type: `element`)_ - The element to get the viewport offset for. - + * `useDocument` _(Type: `boolean`, Default: `false`, optional)_ - Should the viewport be the document element instead of the first scrollable element. - + * `includePadding` _(Type: `boolean`, Default: `true`, optional)_ - Should the padding on the viewport element be accounted for, default is true. @@ -161,21 +179,21 @@ An object with the following properties: * `top` _(Type: `number`)_ - Distance to top content edge of the viewport. - + * `bottom` _(Type: `number`)_ - Distance to bottom content edge of the viewport. - + * `left` _(Type: `number`)_ - Distance to left content edge of the viewport. - + * `right` _(Type: `number`)_ - Distance to right content edge of the viewport. #### parsePlacement(placement) - + Gets an array of placement values parsed from a placement string. Along with the 'auto' indicator, supported placement strings are: * top: element on top, horizontally centered on host element. @@ -208,11 +226,11 @@ An array with the following values: * `[0]` _(Type: `string`)_ - The primary placement. - + * `[1]` _(Type: `string`)_ - The secondary placement. - + * `[2]` _(Type: `boolean`)_ - Is auto place enabled. @@ -226,11 +244,11 @@ Gets gets coordinates for an element to be positioned relative to another elemen * `hostElement` _(Type: `element`)_ - The element to position against. - + * `targetElement` _(Type: `element`)_ - The element to position. - + * `placement` _(Type: `string`, Default: `top`, optional)_ - The placement for the target element. See the parsePlacement() function for available options. If 'auto' placement is used, the viewportOffset() function is used to decide where the targetElement will fit. @@ -246,11 +264,11 @@ An object with the following properties: * `top` _(Type: `number`)_ - The targetElement top value. - + * `left` _(Type: `number`)_ - The targetElement left value. - + * `right` _(Type: `number`)_ - The resolved placement with 'auto' removed. @@ -261,10 +279,10 @@ Positions the tooltip and popover arrow elements when using placement options be ##### parameters -* `element` - _(Type: `element`)_ - +* `element` + _(Type: `element`)_ - The element to position the arrow element for. - + * `placement` _(Type: `string`)_ - The placement for the element. diff --git a/src/position/position.js b/src/position/position.js index 2e78fc4270..282ee78489 100644 --- a/src/position/position.js +++ b/src/position/position.js @@ -90,6 +90,23 @@ angular.module('ui.bootstrap.position', []) return SCROLLBAR_WIDTH; }, + /** + * Checks to see if the element is scrollable. + * + * @param {element} elem - The element to check. + * @param {boolean=} [includeHidden=false] - Should scroll style of 'hidden' be considered, + * default is false. + * + * @returns {boolean} Whether the element is scrollable. + */ + isScrollable: function(elem, includeHidden) { + elem = this.getRawNode(elem); + + var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal; + var elemStyle = $window.getComputedStyle(elem); + return overflowRegex.test(elemStyle.overflow + elemStyle.overflowY + elemStyle.overflowX); + }, + /** * Provides the closest scrollable ancestor. * A port of the jQuery UI scrollParent method: diff --git a/src/position/test/position.spec.js b/src/position/test/position.spec.js index b627876cee..fcc0ea83a3 100644 --- a/src/position/test/position.spec.js +++ b/src/position/test/position.spec.js @@ -231,6 +231,27 @@ describe('$uibPosition service', function () { }); }); + describe('isScrollable', function() { + var el; + + afterEach(function() { + el.remove(); + }); + + it('should return true if the element is scrollable', function() { + el = angular.element('
'); + $document.find('body').append(el); + expect($uibPosition.isScrollable(el)).toBe(true); + }); + + it('should return false if the element is scrollable', function() { + el = angular.element('
'); + $document.find('body').append(el); + expect($uibPosition.isScrollable(el)).toBe(false); + }); + + }); + describe('scrollParent', function() { var el;