(function (factory){ "use strict"; if (typeof define === "function" && define.amd) { define(["jquery", "./version"] , factory); } else { factory(jQuery); } } )(function ($){ "use strict"; (function (){ var cachedScrollbarWidth, max = Math.max, abs = Math.abs, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+(\.[\d]+)?%?/, rposition = /^\w+/, rpercent = /%$/, _position = $.fn.position; function getOffsets(offsets, width, height){ return [parseFloat(offsets[0]) * (rpercent.test(offsets[0])? width / 100: 1), parseFloat(offsets[1]) * (rpercent.test(offsets[1])? height / 100: 1)] ; } function parseCss(element, property){ return parseInt($.css(element, property), 10) || 0; } function isWindow(obj){ return obj != null && obj === obj.window; } function getDimensions(elem){ var raw = elem[0]; if (raw.nodeType === 9) { return { width: elem.width(), height: elem.height(), offset: { top: 0, left: 0} } ; } if (isWindow(raw)) { return { width: elem.width(), height: elem.height(), offset: { top: elem.scrollTop(), left: elem.scrollLeft()} } ; } if (raw.preventDefault) { return { width: 0, height: 0, offset: { top: raw.pageY, left: raw.pageX} } ; } return { width: elem.outerWidth(), height: elem.outerHeight(), offset: elem.offset()} ; } $.position = { scrollbarWidth: function (){ if (cachedScrollbarWidth !== undefined) { return cachedScrollbarWidth; } var w1, w2, div = $("
" + "
"), innerDiv = div.children()[0]; $("body").append(div); w1 = innerDiv.offsetWidth; div.css("overflow", "scroll"); w2 = innerDiv.offsetWidth; if (w1 === w2) { w2 = div[0].clientWidth; } div.remove(); return (cachedScrollbarWidth = w1 - w2); } , getScrollInfo: function (within){ var overflowX = within.isWindow || within.isDocument? "": within.element.css("overflow-x"), overflowY = within.isWindow || within.isDocument? "": within.element.css("overflow-y"), hasOverflowX = overflowX === "scroll" || (overflowX === "auto" && within.width < within.element[0].scrollWidth), hasOverflowY = overflowY === "scroll" || (overflowY === "auto" && within.height < within.element[0].scrollHeight); return { width: hasOverflowY? $.position.scrollbarWidth(): 0, height: hasOverflowX? $.position.scrollbarWidth(): 0} ; } , getWithinInfo: function (element){ var withinElement = $(element || window), isElemWindow = isWindow(withinElement[0]), isDocument = !!withinElement[0] && withinElement[0].nodeType === 9, hasOffset = !isElemWindow && !isDocument; return { element: withinElement, isWindow: isElemWindow, isDocument: isDocument, offset: hasOffset? $(element).offset(): { left: 0, top: 0} , scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), width: withinElement.outerWidth(), height: withinElement.outerHeight()} ; } } ; $.fn.position = function (options){ if (!options || !options.of) { return _position.apply(this, arguments); } options = $.extend({ } , options); var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, target = typeof options.of === "string"? $(document).find(options.of): $(options.of), within = $.position.getWithinInfo(options.within), scrollInfo = $.position.getScrollInfo(within), collision = (options.collision || "flip").split(" "), offsets = { } ; dimensions = getDimensions(target); if (target[0].preventDefault) { options.at = "left top"; } targetWidth = dimensions.width; targetHeight = dimensions.height; targetOffset = dimensions.offset; basePosition = $.extend({ } , targetOffset); $.each(["my", "at"] , function (){ var pos = (options[this] || "").split(" "), horizontalOffset, verticalOffset; if (_AN_Read_length("length", pos) === 1) { pos = rhorizontal.test(pos[0])? pos.concat(["center"] ): rvertical.test(pos[0])? ["center"] .concat(pos): ["center", "center"] ; } pos[0] = rhorizontal.test(pos[0])? pos[0]: "center"; pos[1] = rvertical.test(pos[1])? pos[1]: "center"; horizontalOffset = roffset.exec(pos[0]); verticalOffset = roffset.exec(pos[1]); offsets[this] = [horizontalOffset? horizontalOffset[0]: 0, verticalOffset? verticalOffset[0]: 0] ; options[this] = [rposition.exec(pos[0])[0], rposition.exec(pos[1])[0]] ; } ); if (_AN_Read_length("length", collision) === 1) { collision[1] = collision[0]; } if (options.at[0] === "right") { basePosition.left += targetWidth; } else if (options.at[0] === "center") { basePosition.left += targetWidth / 2; } if (options.at[1] === "bottom") { basePosition.top += targetHeight; } else if (options.at[1] === "center") { basePosition.top += targetHeight / 2; } atOffset = getOffsets(offsets.at, targetWidth, targetHeight); basePosition.left += atOffset[0]; basePosition.top += atOffset[1]; return this.each(function (){ var collisionPosition, using, elem = $(this), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseCss(this, "marginLeft"), marginTop = parseCss(this, "marginTop"), collisionWidth = elemWidth + marginLeft + parseCss(this, "marginRight") + scrollInfo.width, collisionHeight = elemHeight + marginTop + parseCss(this, "marginBottom") + scrollInfo.height, position = $.extend({ } , basePosition), myOffset = getOffsets(offsets.my, elem.outerWidth(), elem.outerHeight()); if (options.my[0] === "right") { position.left -= elemWidth; } else if (options.my[0] === "center") { position.left -= elemWidth / 2; } if (options.my[1] === "bottom") { position.top -= elemHeight; } else if (options.my[1] === "center") { position.top -= elemHeight / 2; } position.left += myOffset[0]; position.top += myOffset[1]; collisionPosition = { marginLeft: marginLeft, marginTop: marginTop} ; $.each(["left", "top"] , function (i, dir){ if ($.ui.position[collision[i]]) { $.ui.position[collision[i]][dir](position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, offset: [atOffset[0] + myOffset[0], atOffset[1] + myOffset[1]] , my: options.my, at: options.at, within: within, elem: elem} ); } } ); if (options.using) { using = function (props){ var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, top = targetOffset.top - position.top, bottom = top + targetHeight - elemHeight, feedback = { target: { element: target, left: targetOffset.left, top: targetOffset.top, width: targetWidth, height: targetHeight} , element: { element: elem, left: position.left, top: position.top, width: elemWidth, height: elemHeight} , horizontal: right < 0? "left": left > 0? "right": "center", vertical: bottom < 0? "top": top > 0? "bottom": "middle"} ; if (targetWidth < elemWidth && abs(left + right) < targetWidth) { feedback.horizontal = "center"; } if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) { feedback.vertical = "middle"; } if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) { feedback.important = "horizontal"; } else { feedback.important = "vertical"; } options.using.call(this, props, feedback); } ; } elem.offset($.extend(position, { using: using} )); } ); } ; $.ui.position = { fit: { left: function (position, data){ var within = data.within, withinOffset = within.isWindow? within.scrollLeft: within.offset.left, outerWidth = within.width, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = withinOffset - collisionPosLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, newOverRight; if (data.collisionWidth > outerWidth) { if (overLeft > 0 && overRight <= 0) { newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; position.left += overLeft - newOverRight; } else if (overRight > 0 && overLeft <= 0) { position.left = withinOffset; } else { if (overLeft > overRight) { position.left = withinOffset + outerWidth - data.collisionWidth; } else { position.left = withinOffset; } } } else if (overLeft > 0) { position.left += overLeft; } else if (overRight > 0) { position.left -= overRight; } else { position.left = max(position.left - collisionPosLeft, position.left); } } , top: function (position, data){ var within = data.within, withinOffset = within.isWindow? within.scrollTop: within.offset.top, outerHeight = data.within.height, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = withinOffset - collisionPosTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, newOverBottom; if (data.collisionHeight > outerHeight) { if (overTop > 0 && overBottom <= 0) { newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; position.top += overTop - newOverBottom; } else if (overBottom > 0 && overTop <= 0) { position.top = withinOffset; } else { if (overTop > overBottom) { position.top = withinOffset + outerHeight - data.collisionHeight; } else { position.top = withinOffset; } } } else if (overTop > 0) { position.top += overTop; } else if (overBottom > 0) { position.top -= overBottom; } else { position.top = max(position.top - collisionPosTop, position.top); } } } , flip: { left: function (position, data){ var within = data.within, withinOffset = within.offset.left + within.scrollLeft, outerWidth = within.width, offsetLeft = within.isWindow? within.scrollLeft: within.offset.left, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = collisionPosLeft - offsetLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, myOffset = data.my[0] === "left"? - data.elemWidth: data.my[0] === "right"? data.elemWidth: 0, atOffset = data.at[0] === "left"? data.targetWidth: data.at[0] === "right"? - data.targetWidth: 0, offset = -2 * data.offset[0], newOverRight, newOverLeft; if (overLeft < 0) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; if (newOverRight < 0 || newOverRight < abs(overLeft)) { position.left += myOffset + atOffset + offset; } } else if (overRight > 0) { newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; if (newOverLeft > 0 || abs(newOverLeft) < overRight) { position.left += myOffset + atOffset + offset; } } } , top: function (position, data){ var within = data.within, withinOffset = within.offset.top + within.scrollTop, outerHeight = within.height, offsetTop = within.isWindow? within.scrollTop: within.offset.top, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = collisionPosTop - offsetTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, top = data.my[1] === "top", myOffset = top? - data.elemHeight: data.my[1] === "bottom"? data.elemHeight: 0, atOffset = data.at[1] === "top"? data.targetHeight: data.at[1] === "bottom"? - data.targetHeight: 0, offset = -2 * data.offset[1], newOverTop, newOverBottom; if (overTop < 0) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; if (newOverBottom < 0 || newOverBottom < abs(overTop)) { position.top += myOffset + atOffset + offset; } } else if (overBottom > 0) { newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; if (newOverTop > 0 || abs(newOverTop) < overBottom) { position.top += myOffset + atOffset + offset; } } } } , flipfit: { left: function (){ $.ui.position.flip.left.apply(this, arguments); $.ui.position.fit.left.apply(this, arguments); } , top: function (){ $.ui.position.flip.top.apply(this, arguments); $.ui.position.fit.top.apply(this, arguments); } } } ; } )(); return $.ui.position; } );