|
|
@@ -173,23 +173,113 @@ function getScrollParent(el) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-// Given a container element, return an object with the pixel values of the left/right scrollbars.
|
|
|
-// Left scrollbars might occur on RTL browsers (IE maybe?) but I have not tested.
|
|
|
-// PREREQUISITE: container element must have a single child with display:block
|
|
|
-function getScrollbarWidths(container) {
|
|
|
- var containerLeft = container.offset().left;
|
|
|
- var containerRight = containerLeft + container.width();
|
|
|
- var inner = container.children();
|
|
|
- var innerLeft = inner.offset().left;
|
|
|
- var innerRight = innerLeft + inner.outerWidth();
|
|
|
+// Queries the outer bounding area of a jQuery element.
|
|
|
+// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
|
|
|
+function getOuterRect(el) {
|
|
|
+ var offset = el.offset();
|
|
|
|
|
|
return {
|
|
|
- left: innerLeft - containerLeft,
|
|
|
- right: containerRight - innerRight
|
|
|
+ left: offset.left,
|
|
|
+ right: offset.left + el.outerWidth(),
|
|
|
+ top: offset.top,
|
|
|
+ bottom: offset.top + el.outerHeight()
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
+// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.
|
|
|
+// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
|
|
|
+// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
|
|
|
+function getClientRect(el) {
|
|
|
+ var offset = el.offset();
|
|
|
+ var scrollbarWidths = getScrollbarWidths(el);
|
|
|
+ var left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left;
|
|
|
+ var top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top;
|
|
|
+
|
|
|
+ return {
|
|
|
+ left: left,
|
|
|
+ right: left + el[0].clientWidth, // clientWidth includes padding but NOT scrollbars
|
|
|
+ top: top,
|
|
|
+ bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.
|
|
|
+// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
|
|
|
+function getContentRect(el) {
|
|
|
+ var offset = el.offset(); // just outside of border, margin not included
|
|
|
+ var left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left');
|
|
|
+ var top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top');
|
|
|
+
|
|
|
+ return {
|
|
|
+ left: left,
|
|
|
+ right: left + el.width(),
|
|
|
+ top: top,
|
|
|
+ bottom: top + el.height()
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.
|
|
|
+// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
|
|
|
+function getScrollbarWidths(el) {
|
|
|
+ var leftRightWidth = el.innerWidth() - el[0].clientWidth; // the paddings cancel out, leaving the scrollbars
|
|
|
+ var widths = {
|
|
|
+ left: 0,
|
|
|
+ right: 0,
|
|
|
+ top: 0,
|
|
|
+ bottom: el.innerHeight() - el[0].clientHeight // the paddings cancel out, leaving the bottom scrollbar
|
|
|
+ };
|
|
|
+
|
|
|
+ if (getIsLeftRtlScrollbars() && el.css('direction') == 'rtl') { // is the scrollbar on the left side?
|
|
|
+ widths.left = leftRightWidth;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ widths.right = leftRightWidth;
|
|
|
+ }
|
|
|
+
|
|
|
+ return widths;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
|
|
|
+
|
|
|
+var _isLeftRtlScrollbars = null;
|
|
|
+
|
|
|
+function getIsLeftRtlScrollbars() { // responsible for caching the computation
|
|
|
+ if (_isLeftRtlScrollbars === null) {
|
|
|
+ _isLeftRtlScrollbars = computeIsLeftRtlScrollbars();
|
|
|
+ }
|
|
|
+ return _isLeftRtlScrollbars;
|
|
|
+}
|
|
|
+
|
|
|
+function computeIsLeftRtlScrollbars() { // creates an offscreen test element, then removes it
|
|
|
+ var el = $('<div><div/></div>')
|
|
|
+ .css({
|
|
|
+ position: 'absolute',
|
|
|
+ top: -1000,
|
|
|
+ left: 0,
|
|
|
+ border: 0,
|
|
|
+ padding: 0,
|
|
|
+ overflow: 'scroll',
|
|
|
+ direction: 'rtl'
|
|
|
+ })
|
|
|
+ .appendTo('body');
|
|
|
+ var innerEl = el.children();
|
|
|
+ var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar?
|
|
|
+ el.remove();
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Retrieves a jQuery element's computed CSS value as a floating-point number.
|
|
|
+// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero.
|
|
|
+function getCssFloat(el, prop) {
|
|
|
+ return parseFloat(el.css(prop)) || 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
|
|
|
function isPrimaryMouseButton(ev) {
|
|
|
return ev.which == 1 && !ev.ctrlKey;
|