summaryrefslogtreecommitdiffstatshomepage
path: root/core/misc/position.js
diff options
context:
space:
mode:
authorcatch <catch@35733.no-reply.drupal.org>2022-09-09 07:26:42 +0100
committercatch <catch@35733.no-reply.drupal.org>2022-09-09 07:26:42 +0100
commit8aa8ce1ffbcca9c727f46e58c714e1d351f7ef88 (patch)
tree27be6908992c340ba0b4c0bd3f4339670aa71e90 /core/misc/position.js
parent09f8f13d8a72b8e482cc689fcd10f023df41b899 (diff)
downloaddrupal-8aa8ce1ffbcca9c727f46e58c714e1d351f7ef88.tar.gz
drupal-8aa8ce1ffbcca9c727f46e58c714e1d351f7ef88.zip
Issue #3278415 by nod_, lauriii, catch, Wim Leers, longwave, xjm, claudiu.cristea: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies
Diffstat (limited to 'core/misc/position.js')
-rw-r--r--core/misc/position.js438
1 files changed, 315 insertions, 123 deletions
diff --git a/core/misc/position.js b/core/misc/position.js
index 6faf9c122fe..a42f2331f24 100644
--- a/core/misc/position.js
+++ b/core/misc/position.js
@@ -1,16 +1,30 @@
/**
-* DO NOT EDIT THIS FILE.
-* See the following change record for more information,
-* https://www.drupal.org/node/2815083
-* @preserve
-**/
+ * @file
+ * A modified version of jQuery UI position.
+ *
+ * Per jQuery UI's public domain license, it is permissible to run modified
+ * versions of their code. This file offers the same functionality as what is
+ * provided by jQuery UI position, but refactored to meet Drupal coding
+ * standards, and restructured so it extends jQuery core instead of jQuery UI.
+ *
+ * This is provided to support pre-existing code that expects the jQuery
+ * position API.
+ *
+ * @see https://github.com/jquery/jquery-ui/blob/1.12.1/LICENSE.txt
+ * @see https://raw.githubusercontent.com/jquery/jquery-ui/1.12.1/ui/position.js
+ */
-($ => {
+/**
+ * This provides ported version of jQuery UI position, refactored to not depend
+ * on jQuery UI and to meet Drupal JavaScript coding standards. Functionality
+ * and usage is identical. It positions an element relative to another. The
+ * `position()` function can be called by any jQuery object. Additional details
+ * on using `position()` are provided in this file in the docblock for
+ * $.fn.position.
+ */
+(($) => {
let cachedScrollbarWidth = null;
- const {
- max,
- abs
- } = Math;
+ const { max, abs } = Math;
const regexHorizontal = /left|center|right/;
const regexVertical = /top|center|bottom/;
const regexOffset = /[+-]\d+(\.[\d]+)?%?/;
@@ -19,7 +33,12 @@
const _position = $.fn.position;
function getOffsets(offsets, width, height) {
- return [parseFloat(offsets[0]) * (regexPercent.test(offsets[0]) ? width / 100 : 1), parseFloat(offsets[1]) * (regexPercent.test(offsets[1]) ? height / 100 : 1)];
+ return [
+ parseFloat(offsets[0]) *
+ (regexPercent.test(offsets[0]) ? width / 100 : 1),
+ parseFloat(offsets[1]) *
+ (regexPercent.test(offsets[1]) ? height / 100 : 1),
+ ];
}
function parseCss(element, property) {
@@ -28,209 +47,272 @@
function getDimensions(elem) {
const raw = elem[0];
-
if (raw.nodeType === 9) {
return {
width: elem.width(),
height: elem.height(),
- offset: {
- top: 0,
- left: 0
- }
+ offset: { top: 0, left: 0 },
};
}
-
if ($.isWindow(raw)) {
return {
width: elem.width(),
height: elem.height(),
- offset: {
- top: elem.scrollTop(),
- left: elem.scrollLeft()
- }
+ offset: { top: elem.scrollTop(), left: elem.scrollLeft() },
};
}
-
if (raw.preventDefault) {
return {
width: 0,
height: 0,
- offset: {
- top: raw.pageY,
- left: raw.pageX
- }
+ offset: { top: raw.pageY, left: raw.pageX },
};
}
-
return {
width: elem.outerWidth(),
height: elem.outerHeight(),
- offset: elem.offset()
+ offset: elem.offset(),
};
}
const collisions = {
fit: {
left(position, data) {
- const {
- within
- } = data;
- const withinOffset = within.isWindow ? within.scrollLeft : within.offset.left;
+ const { within } = data;
+ const withinOffset = within.isWindow
+ ? within.scrollLeft
+ : within.offset.left;
const outerWidth = within.width;
- const collisionPosLeft = position.left - data.collisionPosition.marginLeft;
+ const collisionPosLeft =
+ position.left - data.collisionPosition.marginLeft;
const overLeft = withinOffset - collisionPosLeft;
- const overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset;
+ const overRight =
+ collisionPosLeft + data.collisionWidth - outerWidth - withinOffset;
let newOverRight;
+ // Element is wider than within
if (data.collisionWidth > outerWidth) {
+ // Element is initially over the left side of within
if (overLeft > 0 && overRight <= 0) {
- newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
+ newOverRight =
+ position.left +
+ overLeft +
+ data.collisionWidth -
+ outerWidth -
+ withinOffset;
position.left += overLeft - newOverRight;
+
+ // Element is initially over right side of within
} else if (overRight > 0 && overLeft <= 0) {
position.left = withinOffset;
+
+ // Element is initially over both left and right sides of within
} else if (overLeft > overRight) {
position.left = withinOffset + outerWidth - data.collisionWidth;
} else {
position.left = withinOffset;
}
+
+ // Too far left -> align with left edge
} else if (overLeft > 0) {
position.left += overLeft;
+
+ // Too far right -> align with right edge
} else if (overRight > 0) {
position.left -= overRight;
+
+ // Adjust based on position and margin
} else {
position.left = max(position.left - collisionPosLeft, position.left);
}
},
-
top(position, data) {
- const {
- within
- } = data;
- const withinOffset = within.isWindow ? within.scrollTop : within.offset.top;
+ const { within } = data;
+ const withinOffset = within.isWindow
+ ? within.scrollTop
+ : within.offset.top;
const outerHeight = data.within.height;
const collisionPosTop = position.top - data.collisionPosition.marginTop;
const overTop = withinOffset - collisionPosTop;
- const overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset;
+ const overBottom =
+ collisionPosTop + data.collisionHeight - outerHeight - withinOffset;
let newOverBottom;
+ // Element is taller than within
if (data.collisionHeight > outerHeight) {
+ // Element is initially over the top of within
if (overTop > 0 && overBottom <= 0) {
- newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
+ newOverBottom =
+ position.top +
+ overTop +
+ data.collisionHeight -
+ outerHeight -
+ withinOffset;
position.top += overTop - newOverBottom;
+
+ // Element is initially over bottom of within
} else if (overBottom > 0 && overTop <= 0) {
position.top = withinOffset;
+
+ // Element is initially over both top and bottom of within
} else if (overTop > overBottom) {
position.top = withinOffset + outerHeight - data.collisionHeight;
} else {
position.top = withinOffset;
}
+
+ // Too far up -> align with top
} else if (overTop > 0) {
position.top += overTop;
+
+ // Too far down -> align with bottom edge
} else if (overBottom > 0) {
position.top -= overBottom;
+
+ // Adjust based on position and margin
} else {
position.top = max(position.top - collisionPosTop, position.top);
}
- }
-
+ },
},
flip: {
left(position, data) {
- const {
- within
- } = data;
+ const { within } = data;
const withinOffset = within.offset.left + within.scrollLeft;
const outerWidth = within.width;
- const offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left;
- const collisionPosLeft = position.left - data.collisionPosition.marginLeft;
+ const offsetLeft = within.isWindow
+ ? within.scrollLeft
+ : within.offset.left;
+ const collisionPosLeft =
+ position.left - data.collisionPosition.marginLeft;
const overLeft = collisionPosLeft - offsetLeft;
- const overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft;
- const myOffset = data.my[0] === 'left' ? -data.elemWidth : data.my[0] === 'right' ? data.elemWidth : 0;
- const atOffset = data.at[0] === 'left' ? data.targetWidth : data.at[0] === 'right' ? -data.targetWidth : 0;
+ const overRight =
+ collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft;
+ const myOffset =
+ // eslint-disable-next-line no-nested-ternary
+ data.my[0] === 'left'
+ ? -data.elemWidth
+ : data.my[0] === 'right'
+ ? data.elemWidth
+ : 0;
+ const atOffset =
+ // eslint-disable-next-line no-nested-ternary
+ data.at[0] === 'left'
+ ? data.targetWidth
+ : data.at[0] === 'right'
+ ? -data.targetWidth
+ : 0;
const offset = -2 * data.offset[0];
let newOverRight;
let newOverLeft;
if (overLeft < 0) {
- newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
-
+ 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;
-
+ newOverLeft =
+ position.left -
+ data.collisionPosition.marginLeft +
+ myOffset +
+ atOffset +
+ offset -
+ offsetLeft;
if (newOverLeft > 0 || abs(newOverLeft) < overRight) {
position.left += myOffset + atOffset + offset;
}
}
},
-
top(position, data) {
- const {
- within
- } = data;
+ const { within } = data;
const withinOffset = within.offset.top + within.scrollTop;
const outerHeight = within.height;
- const offsetTop = within.isWindow ? within.scrollTop : within.offset.top;
+ const offsetTop = within.isWindow
+ ? within.scrollTop
+ : within.offset.top;
const collisionPosTop = position.top - data.collisionPosition.marginTop;
const overTop = collisionPosTop - offsetTop;
- const overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop;
+ const overBottom =
+ collisionPosTop + data.collisionHeight - outerHeight - offsetTop;
const top = data.my[1] === 'top';
- const myOffset = top ? -data.elemHeight : data.my[1] === 'bottom' ? data.elemHeight : 0;
- const atOffset = data.at[1] === 'top' ? data.targetHeight : data.at[1] === 'bottom' ? -data.targetHeight : 0;
+ // eslint-disable-next-line no-nested-ternary
+ const myOffset = top
+ ? -data.elemHeight
+ : data.my[1] === 'bottom'
+ ? data.elemHeight
+ : 0;
+ const atOffset =
+ // eslint-disable-next-line no-nested-ternary
+ data.at[1] === 'top'
+ ? data.targetHeight
+ : data.at[1] === 'bottom'
+ ? -data.targetHeight
+ : 0;
const offset = -2 * data.offset[1];
let newOverTop;
let newOverBottom;
-
if (overTop < 0) {
- newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
-
+ 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;
-
+ newOverTop =
+ position.top -
+ data.collisionPosition.marginTop +
+ myOffset +
+ atOffset +
+ offset -
+ offsetTop;
if (newOverTop > 0 || abs(newOverTop) < overBottom) {
position.top += myOffset + atOffset + offset;
}
}
- }
-
+ },
},
flipfit: {
- left() {
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
+ left(...args) {
collisions.flip.left.apply(this, args);
collisions.fit.left.apply(this, args);
},
-
- top() {
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
+ top(...args) {
collisions.flip.top.apply(this, args);
collisions.fit.top.apply(this, args);
- }
-
- }
+ },
+ },
};
+
$.position = {
scrollbarWidth() {
if (cachedScrollbarWidth !== undefined) {
return cachedScrollbarWidth;
}
-
- const div = $('<div ' + "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + "<div style='height:100px;width:auto;'></div></div>");
+ const div = $(
+ '<div ' +
+ "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
+ "<div style='height:100px;width:auto;'></div></div>",
+ );
const innerDiv = div.children()[0];
+
$('body').append(div);
const w1 = innerDiv.offsetWidth;
div.css('overflow', 'scroll');
+
let w2 = innerDiv.offsetWidth;
if (w1 === w2) {
@@ -241,18 +323,27 @@
cachedScrollbarWidth = w1 - w2;
return cachedScrollbarWidth;
},
-
getScrollInfo(within) {
- const overflowX = within.isWindow || within.isDocument ? '' : within.element.css('overflow-x');
- const overflowY = within.isWindow || within.isDocument ? '' : within.element.css('overflow-y');
- const hasOverflowX = overflowX === 'scroll' || overflowX === 'auto' && within.width < within.element[0].scrollWidth;
- const hasOverflowY = overflowY === 'scroll' || overflowY === 'auto' && within.height < within.element[0].scrollHeight;
+ const overflowX =
+ within.isWindow || within.isDocument
+ ? ''
+ : within.element.css('overflow-x');
+ const overflowY =
+ within.isWindow || within.isDocument
+ ? ''
+ : within.element.css('overflow-y');
+ const hasOverflowX =
+ overflowX === 'scroll' ||
+ (overflowX === 'auto' && within.width < within.element[0].scrollWidth);
+ const hasOverflowY =
+ overflowY === 'scroll' ||
+ (overflowY === 'auto' &&
+ within.height < within.element[0].scrollHeight);
return {
width: hasOverflowY ? $.position.scrollbarWidth() : 0,
- height: hasOverflowX ? $.position.scrollbarWidth() : 0
+ height: hasOverflowX ? $.position.scrollbarWidth() : 0,
};
},
-
getWithinInfo(element) {
const withinElement = $(element || window);
const isWindow = $.isWindow(withinElement[0]);
@@ -262,56 +353,139 @@
element: withinElement,
isWindow,
isDocument,
- offset: hasOffset ? $(element).offset() : {
- left: 0,
- top: 0
- },
+ offset: hasOffset ? $(element).offset() : { left: 0, top: 0 },
scrollLeft: withinElement.scrollLeft(),
scrollTop: withinElement.scrollTop(),
width: withinElement.outerWidth(),
- height: withinElement.outerHeight()
+ height: withinElement.outerHeight(),
};
- }
-
+ },
};
+ // eslint-disable-next-line func-names
+ /**
+ * Positions an element relative to another.
+ *
+ * The following documentation is originally from
+ * {@link https://api.jqueryui.com/position/}.
+ *
+ * @param {Object} options - the options object.
+ * @param {string} options.my - Defines which position on the element being
+ * positioned to align with the target element: "horizontal vertical"
+ * alignment. A single value such as "right" will be normalized to "right
+ * center", "top" will be normalized to "center top" (following CSS
+ * convention). Acceptable horizontal values: "left", "center", "right".
+ * Acceptable vertical values: "top", "center", "bottom". Example: "left
+ * top" or "center center". Each dimension can also contain offsets, in
+ * pixels or percent, e.g., "right+10 top-25%". Percentage offsets are
+ * relative to the element being positioned. Default value is "center".
+ * @param {string} options.at - Defines which position on the target element
+ * to align the positioned element against: "horizontal vertical" alignment.
+ * See the `my` option for full details on possible values. Percentage
+ * offsets are relative to the target element. Default value is "center".
+ * @param {string|Element|jQuery|Event|null} options.of - Which element to
+ * position against. If you provide a selector or jQuery object, the first
+ * matching element will be used. If you provide an event object, the pageX
+ * and pageY properties will be used. Example: "#top-menu". Default value is
+ * null.
+ * @param {string} options.collision - When the positioned element overflows
+ * the window in some direction, move it to an alternative position. Similar
+ * to `my` and `at`, this accepts a single value or a pair for
+ * horizontal/vertical, e.g., "flip", "fit", "fit flip", "fit none". Default
+ * value is "flip". The options work as follows:
+ * - "flip": Flips the element to the opposite side of the target and the
+ * collision detection is run again to see if it will fit. Whichever side
+ * allows more of the element to be visible will be used.
+ * - "fit": Shift the element away from the edge of the window.
+ * - "flipfit": First applies the flip logic, placing the element on
+ * whichever side allows more of the element to be visible. Then the fit
+ * logic is applied to ensure as much of the element is visible as
+ * possible.
+ * "none": Does not apply any collision detection.
+ * @param {function|null} options.using - When specified, the actual property
+ * setting is delegated to this callback. Receives two parameters: The first
+ * is a hash of top and left values for the position that should be set and
+ * can be forwarded to .css() or .animate().The second provides feedback
+ * about the position and dimensions of both elements, as well as
+ * calculations to their relative position. Both target and element have
+ * these properties: element, left, top, width, height. In addition, there's
+ * horizontal, vertical and important, providing twelve potential directions
+ * like { horizontal: "center", vertical: "left", important: "horizontal" }.
+ * Default value is null.
+ * @param {string|Element|jQuery} options.within - Element to position within,
+ * affecting collision detection. If you provide a selector or jQuery
+ * object, the first matching element will be used. Default value is window.
+ *
+ * @return {jQuery}
+ * The jQuery object that called called this function.
+ */
$.fn.position = function (options) {
if (!options || !options.of) {
+ // eslint-disable-next-line prefer-rest-params
return _position.apply(this, arguments);
}
+ // Make a copy, we don't want to modify arguments
options = $.extend({}, options);
+
const within = $.position.getWithinInfo(options.within);
const scrollInfo = $.position.getScrollInfo(within);
const collision = (options.collision || 'flip').split(' ');
const offsets = {};
- const target = typeof options.of === 'string' ? $(document).find(options.of) : $(options.of);
+
+ // Make sure string options are treated as CSS selectors
+ const target =
+ typeof options.of === 'string'
+ ? $(document).find(options.of)
+ : $(options.of);
const dimensions = getDimensions(target);
const targetWidth = dimensions.width;
const targetHeight = dimensions.height;
const targetOffset = dimensions.offset;
if (target[0].preventDefault) {
+ // Force left top to allow flipping
options.at = 'left top';
}
+ // Clone to reuse original targetOffset later
const basePosition = $.extend({}, targetOffset);
+
+ // Force my and at to have valid horizontal and vertical positions
+ // if a value is missing or invalid, it will be converted to center
+ // eslint-disable-next-line func-names
$.each(['my', 'at'], function () {
let pos = (options[this] || '').split(' ');
if (pos.length === 1) {
- pos = regexHorizontal.test(pos[0]) ? pos.concat(['center']) : regexVertical.test(pos[0]) ? ['center'].concat(pos) : ['center', 'center'];
+ // eslint-disable-next-line no-nested-ternary
+ pos = regexHorizontal.test(pos[0])
+ ? pos.concat(['center'])
+ : regexVertical.test(pos[0])
+ ? ['center'].concat(pos)
+ : ['center', 'center'];
}
-
pos[0] = regexHorizontal.test(pos[0]) ? pos[0] : 'center';
pos[1] = regexVertical.test(pos[1]) ? pos[1] : 'center';
+
+ // Calculate offsets
const horizontalOffset = regexOffset.exec(pos[0]);
const verticalOffset = regexOffset.exec(pos[1]);
- offsets[this] = [horizontalOffset ? horizontalOffset[0] : 0, verticalOffset ? verticalOffset[0] : 0];
- options[this] = [regexPosition.exec(pos[0])[0], regexPosition.exec(pos[1])[0]];
+ offsets[this] = [
+ horizontalOffset ? horizontalOffset[0] : 0,
+ verticalOffset ? verticalOffset[0] : 0,
+ ];
+
+ // Reduce to just the positions without the offsets
+ options[this] = [
+ regexPosition.exec(pos[0])[0],
+ regexPosition.exec(pos[1])[0],
+ ];
});
+ // Normalize collision option
if (collision.length === 1) {
+ // eslint-disable-next-line prefer-destructuring
collision[1] = collision[0];
}
@@ -330,6 +504,8 @@
const atOffset = getOffsets(offsets.at, targetWidth, targetHeight);
basePosition.left += atOffset[0];
basePosition.top += atOffset[1];
+
+ // eslint-disable-next-line func-names
return this.each(function () {
let using;
const elem = $(this);
@@ -337,10 +513,22 @@
const elemHeight = elem.outerHeight();
const marginLeft = parseCss(this, 'marginLeft');
const marginTop = parseCss(this, 'marginTop');
- const collisionWidth = elemWidth + marginLeft + parseCss(this, 'marginRight') + scrollInfo.width;
- const collisionHeight = elemHeight + marginTop + parseCss(this, 'marginBottom') + scrollInfo.height;
+ const collisionWidth =
+ elemWidth +
+ marginLeft +
+ parseCss(this, 'marginRight') +
+ scrollInfo.width;
+ const collisionHeight =
+ elemHeight +
+ marginTop +
+ parseCss(this, 'marginBottom') +
+ scrollInfo.height;
const position = $.extend({}, basePosition);
- const myOffset = getOffsets(offsets.my, elem.outerWidth(), elem.outerHeight());
+ const myOffset = getOffsets(
+ offsets.my,
+ elem.outerWidth(),
+ elem.outerHeight(),
+ );
if (options.my[0] === 'right') {
position.left -= elemWidth;
@@ -356,10 +544,13 @@
position.left += myOffset[0];
position.top += myOffset[1];
+
const collisionPosition = {
marginLeft,
- marginTop
+ marginTop,
};
+
+ // eslint-disable-next-line func-names
$.each(['left', 'top'], function (i, dir) {
if (collisions[collision[i]]) {
collisions[collision[i]][dir](position, {
@@ -374,12 +565,14 @@
my: options.my,
at: options.at,
within,
- elem
+ elem,
});
}
});
if (options.using) {
+ // Adds feedback as second argument to using callback, if present
+ // eslint-disable-next-line func-names
using = function (props) {
const left = targetOffset.left - position.left;
const right = left + targetWidth - elemWidth;
@@ -391,46 +584,45 @@
left: targetOffset.left,
top: targetOffset.top,
width: targetWidth,
- height: targetHeight
+ height: targetHeight,
},
element: {
element: elem,
left: position.left,
top: position.top,
width: elemWidth,
- height: elemHeight
+ height: elemHeight,
},
+ // eslint-disable-next-line no-nested-ternary
horizontal: right < 0 ? 'left' : left > 0 ? 'right' : 'center',
- vertical: bottom < 0 ? 'top' : top > 0 ? 'bottom' : 'middle'
+ // eslint-disable-next-line no-nested-ternary
+ 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
- }));
+ elem.offset($.extend(position, { using }));
});
};
+ // Although $.ui.position is not built to be called directly, some legacy code
+ // may have checks for the presence of $.ui.position, which can be used to
+ // confirm the presence of jQuery UI position's API, as opposed to the more
+ // limited version provided by jQuery.
if (!$.hasOwnProperty('ui')) {
$.ui = {};
}
-
$.ui.position = collisions;
-})(jQuery); \ No newline at end of file
+})(jQuery);