in site/semantic/src/definitions/modules/popup.js [727:912]
position: function(position, calculations) {
// exit conditions
if($target.length === 0 || $popup.length === 0) {
module.error(error.notFound);
return;
}
var
offset,
distanceAway,
target,
popup,
parent,
positioning,
popupOffset,
distanceFromBoundary
;
calculations = calculations || module.get.calculations();
position = position || $module.data(metadata.position) || settings.position;
offset = $module.data(metadata.offset) || settings.offset;
distanceAway = settings.distanceAway;
// shorthand
target = calculations.target;
popup = calculations.popup;
parent = calculations.parent;
if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
module.debug('Popup target is hidden, no action taken');
return false;
}
if(settings.inline) {
module.debug('Adding margin to calculation', target.margin);
if(position == 'left center' || position == 'right center') {
offset += target.margin.top;
distanceAway += -target.margin.left;
}
else if (position == 'top left' || position == 'top center' || position == 'top right') {
offset += target.margin.left;
distanceAway -= target.margin.top;
}
else {
offset += target.margin.left;
distanceAway += target.margin.top;
}
}
module.debug('Determining popup position from calculations', position, calculations);
if (module.is.rtl()) {
position = position.replace(/left|right/g, function (match) {
return (match == 'left')
? 'right'
: 'left'
;
});
module.debug('RTL: Popup position updated', position);
}
// if last attempt use specified last resort position
if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
position = settings.lastResort;
}
switch (position) {
case 'top left':
positioning = {
top : 'auto',
bottom : parent.height - target.top + distanceAway,
left : target.left + offset,
right : 'auto'
};
break;
case 'top center':
positioning = {
bottom : parent.height - target.top + distanceAway,
left : target.left + (target.width / 2) - (popup.width / 2) + offset,
top : 'auto',
right : 'auto'
};
break;
case 'top right':
positioning = {
bottom : parent.height - target.top + distanceAway,
right : parent.width - target.left - target.width - offset,
top : 'auto',
left : 'auto'
};
break;
case 'left center':
positioning = {
top : target.top + (target.height / 2) - (popup.height / 2) + offset,
right : parent.width - target.left + distanceAway,
left : 'auto',
bottom : 'auto'
};
break;
case 'right center':
positioning = {
top : target.top + (target.height / 2) - (popup.height / 2) + offset,
left : target.left + target.width + distanceAway,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom left':
positioning = {
top : target.top + target.height + distanceAway,
left : target.left + offset,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom center':
positioning = {
top : target.top + target.height + distanceAway,
left : target.left + (target.width / 2) - (popup.width / 2) + offset,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom right':
positioning = {
top : target.top + target.height + distanceAway,
right : parent.width - target.left - target.width - offset,
left : 'auto',
bottom : 'auto'
};
break;
}
if(positioning === undefined) {
module.error(error.invalidPosition, position);
}
module.debug('Calculated popup positioning values', positioning);
// tentatively place on stage
$popup
.css(positioning)
.removeClass(className.position)
.addClass(position)
.addClass(className.loading)
;
popupOffset = module.get.popupOffset();
// see if any boundaries are surpassed with this tentative position
distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
if( module.is.offstage(distanceFromBoundary, position) ) {
module.debug('Position is outside viewport', position);
if(searchDepth < settings.maxSearchDepth) {
searchDepth++;
position = module.get.nextPosition(position);
module.debug('Trying new position', position);
return ($popup)
? module.set.position(position, calculations)
: false
;
}
else {
if(settings.lastResort) {
module.debug('No position found, showing with last position');
}
else {
module.debug('Popup could not find a position to display', $popup);
module.error(error.cannotPlace, element);
module.remove.attempts();
module.remove.loading();
module.reset();
settings.onUnplaceable.call($popup, element);
return false;
}
}
}
module.debug('Position is on stage', position);
module.remove.attempts();
module.remove.loading();
if( settings.setFluidWidth && module.is.fluid() ) {
module.set.fluidWidth(calculations);
}
return true;
},