From 63f8c0c71d7e9a939d038c36db16ada6ea7edb41 Mon Sep 17 00:00:00 2001 From: belerweb Date: Sat, 13 Jul 2013 14:27:50 +0800 Subject: [PATCH] Fix 'bootstrap popover falls off page if editable is too close to window edge' Fix 'bootstrap popover falls off page if editable is too close to window edge'. Reference: https://github.com/twitter/bootstrap/pull/6713 https://github.com/twitter/bootstrap/issues/7399 https://gist.github.com/nonumber/5257443 --- src/containers/editable-popover.js | 96 +++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/src/containers/editable-popover.js b/src/containers/editable-popover.js index e520f6f0..e781f408 100644 --- a/src/containers/editable-popover.js +++ b/src/containers/editable-popover.js @@ -67,7 +67,11 @@ , actualWidth , actualHeight , placement - , tp; + , tp + , tpt + , tpb + , tpl + , tpr; placement = typeof this.options.placement === 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : @@ -87,20 +91,80 @@ actualWidth = $tip[0].offsetWidth; actualHeight = $tip[0].offsetHeight; - switch (inside ? placement.split(' ')[1] : placement) { - case 'bottom': - tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 'top': - tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 'left': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}; - break; - case 'right': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}; - break; - } + placement = inside ? placement.split(' ')[1] : placement; + + tpb = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} + tpt = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} + tpl = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} + tpr = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} + + switch (placement) { + case 'bottom': + if ((tpb.top + actualHeight) > ($(window).scrollTop() + $(window).height())) { + if (tpt.top > $(window).scrollTop()) { + placement = 'top' + } else if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) { + placement = 'right' + } else if (tpl.left > $(window).scrollLeft()) { + placement = 'left' + } else { + placement = 'right' + } + } + break + case 'top': + if (tpt.top < $(window).scrollTop()) { + if ((tpb.top + actualHeight) < ($(window).scrollTop() + $(window).height())) { + placement = 'bottom' + } else if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) { + placement = 'right' + } else if (tpl.left > $(window).scrollLeft()) { + placement = 'left' + } else { + placement = 'right' + } + } + break + case 'left': + if (tpl.left < $(window).scrollLeft()) { + if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) { + placement = 'right' + } else if (tpt.top > $(window).scrollTop()) { + placement = 'top' + } else if (tpt.top > $(window).scrollTop()) { + placement = 'bottom' + } else { + placement = 'right' + } + } + break + case 'right': + if ((tpr.left + actualWidth) > ($(window).scrollLeft() + $(window).width())) { + if (tpl.left > $(window).scrollLeft()) { + placement = 'left' + } else if (tpt.top > $(window).scrollTop()) { + placement = 'top' + } else if (tpt.top > $(window).scrollTop()) { + placement = 'bottom' + } + } + break + } + + switch (placement) { + case 'bottom': + tp = tpb; + break + case 'top': + tp = tpt; + break + case 'left': + tp = tpl; + break + case 'right': + tp = tpr; + break + } $tip .offset(tp) @@ -112,4 +176,4 @@ } }); -}(window.jQuery)); \ No newline at end of file +}(window.jQuery));