From e3bf521edbd0c6f59aba9aa9a89a9d96e1da3fd2 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 9 Jun 2021 21:45:13 +0200 Subject: [PATCH] luci-base: ui.js: determine dropdown position relative to overflow parent Signed-off-by: Jo-Philipp Wich --- .../htdocs/luci-static/resources/ui.js | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index 5a0e6d297b..0e909b6dcc 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -1201,6 +1201,28 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { return sb; }, + /** @private */ + getScrollParent: function(element) { + var parent = element, + style = getComputedStyle(element), + excludeStaticParent = (style.position === 'absolute'); + + if (style.position === 'fixed') + return document.body; + + while ((parent = parent.parentElement) != null) { + style = getComputedStyle(parent); + + if (excludeStaticParent && style.position === 'static') + continue; + + if (/(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX)) + return parent; + } + + return document.body; + }, + /** @private */ openDropdown: function(sb) { var st = window.getComputedStyle(sb, null), @@ -1209,7 +1231,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { fl = findParent(sb, '.cbi-value-field'), sel = ul.querySelector('[selected]'), rect = sb.getBoundingClientRect(), - items = Math.min(this.options.dropdown_items, li.length); + items = Math.min(this.options.dropdown_items, li.length), + scrollParent = this.getScrollParent(sb); document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) { s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {})); @@ -1234,29 +1257,7 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { ul.style.maxHeight = (vpHeight * 0.5) + 'px'; ul.style.WebkitOverflowScrolling = 'touch'; - var getScrollParent = function(element) { - var parent = element, - style = getComputedStyle(element), - excludeStaticParent = (style.position === 'absolute'); - - if (style.position === 'fixed') - return document.body; - - while ((parent = parent.parentElement) != null) { - style = getComputedStyle(parent); - - if (excludeStaticParent && style.position === 'static') - continue; - - if (/(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX)) - return parent; - } - - return document.body; - } - - var scrollParent = getScrollParent(sb), - scrollFrom = scrollParent.scrollTop, + var scrollFrom = scrollParent.scrollTop, scrollTo = scrollFrom + rect.top - vpHeight * 0.5; var scrollStep = function(timestamp) { @@ -1282,10 +1283,11 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { ul.style.top = ul.style.bottom = ''; window.requestAnimationFrame(function() { - var itemHeight = li[Math.max(0, li.length - 2)].getBoundingClientRect().height, + var containerRect = scrollParent.getBoundingClientRect(), + itemHeight = li[Math.max(0, li.length - 2)].getBoundingClientRect().height, fullHeight = 0, - spaceAbove = rect.top, - spaceBelow = window.innerHeight - rect.height - rect.top; + spaceAbove = rect.top - containerRect.top, + spaceBelow = containerRect.bottom - rect.bottom; for (var i = 0; i < (items == -1 ? li.length : items); i++) fullHeight += li[i].getBoundingClientRect().height; -- 2.30.2