bootstrap: Patch popover position calculations.

For large popovers (and tooltips) we want to avoid
having the popovers go offscreen.

Fixes #11469.
This commit is contained in:
Steve Howell 2019-02-11 21:42:20 +00:00 committed by Tim Abbott
parent 5442b38a20
commit 21ccf45db9
1 changed files with 39 additions and 4 deletions

View File

@ -1224,6 +1224,8 @@
, placement , placement
, tp , tp
, newtop , newtop
, left
, top
if (this.hasContent() && this.enabled) { if (this.hasContent() && this.enabled) {
$tip = this.tip() $tip = this.tip()
@ -1251,19 +1253,52 @@
switch (inside ? placement.split(' ')[1] : placement) { switch (inside ? placement.split(' ')[1] : placement) {
case 'bottom': case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} top = pos.top + pos.height;
left = pos.left + pos.width / 2 - actualWidth / 2;
break break
case 'top': case 'top':
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} top = pos.top - actualHeight;
left = pos.left + pos.width / 2 - actualWidth / 2;
break break
case 'left': case 'left':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} top = pos.top + pos.height / 2 - actualHeight / 2;
left = pos.left - actualWidth;
break break
case 'right': case 'right':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} top = pos.top + pos.height / 2 - actualHeight / 2;
left = pos.left + pos.width;
break break
} }
if (this.options.fix_positions) {
var win_height = $(window).height();
var win_width = $(window).width();
/* Ensure that the popover stays fully onscreen,
as best as we can. It might still not look
great--in some cases, we should probably just
center--but this patch makes the popover more
likely to be usable. (If the screen is super
small, obviously we can't fit it completely.)
If you use this fix_positions option, you want
to also use the "no_arrow_popover" template.
*/
if (top < 0) {
top = 0;
} else if (top + actualHeight > win_height) {
top = win_height - actualHeight;
}
if (left < 0) {
left = 0;
} else if (left + actualWidth > win_width) {
left = win_width - actualWidth;
}
}
tp = {top: top, left: left};
if (this.options.fixed) { if (this.options.fixed) {
// If using position: fixed, position relative to top of // If using position: fixed, position relative to top of
// viewport // viewport