diff --git a/src/web/OperationsWaiter.js b/src/web/OperationsWaiter.js index 992b737e..168cff9e 100755 --- a/src/web/OperationsWaiter.js +++ b/src/web/OperationsWaiter.js @@ -155,7 +155,35 @@ OperationsWaiter.prototype.getSelectedOp = function(ops) { */ OperationsWaiter.prototype.opListCreate = function(e) { this.manager.recipe.createSortableSeedList(e.target); - $("[data-toggle=popover]").popover(); + this.enableOpsListPopovers(e.target); +}; + + +/** + * Sets up popovers, allowing the popover itself to gain focus which enables scrolling + * and other interactions. + * + * @param {Element} el - The element to start selecting from + */ +OperationsWaiter.prototype.enableOpsListPopovers = function(el) { + $(el).find("[data-toggle=popover]").addBack("[data-toggle=popover]") + .popover({trigger: "manual"}) + .on("mouseenter", function() { + const _this = this; + $(this).popover("show"); + $(".popover").on("mouseleave", function () { + $(_this).popover("hide"); + }); + }).on("mouseleave", function () { + const _this = this; + setTimeout(function() { + // Determine if the popover associated with this element is being hovered over + if ($(_this).data("bs.popover") && + !$(_this).data("bs.popover").$tip.is(":hover")) { + $(_this).popover("hide"); + } + }, 50); + }); }; diff --git a/src/web/RecipeWaiter.js b/src/web/RecipeWaiter.js index 63233127..ea09d325 100755 --- a/src/web/RecipeWaiter.js +++ b/src/web/RecipeWaiter.js @@ -93,7 +93,7 @@ RecipeWaiter.prototype.createSortableSeedList = function(listEl) { // Removes popover element and event bindings from the dragged operation but not the // event bindings from the one left in the operations list. Without manually removing // these bindings, we cannot re-initialise the popover on the stub operation. - $(evt.item).popover("destroy"); + $(evt.item).popover("destroy").removeData("bs.popover").off("mouseenter").off("mouseleave"); $(evt.clone).off(".popover").removeData("bs.popover"); evt.item.setAttribute("data-toggle", "popover-disabled"); }, @@ -120,8 +120,7 @@ RecipeWaiter.prototype.opSortEnd = function(evt) { // Reinitialise the popover on the original element in the ops list because for some reason it // gets destroyed and recreated. - $(evt.clone).popover(); - $(evt.clone).children("[data-toggle=popover]").popover(); + this.manager.ops.enableOpsListPopovers(evt.clone); if (evt.item.parentNode.id !== "rec-list") { return; diff --git a/src/web/stylesheets/utils/_overrides.css b/src/web/stylesheets/utils/_overrides.css index 8957071a..36069cd5 100755 --- a/src/web/stylesheets/utils/_overrides.css +++ b/src/web/stylesheets/utils/_overrides.css @@ -142,6 +142,10 @@ optgroup { border-color: var(--popover-border-colour); } +.popover-content { + max-height: 90vh; + overflow-y: auto; +} .popover.right>.arrow { border-right-color: var(--popover-border-colour);