luci-base: ui.js: determine dropdown position relative to overflow parent
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
fb82e03635
commit
e3bf521edb
1 changed files with 29 additions and 27 deletions
|
@ -1201,6 +1201,28 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
|
||||||
return sb;
|
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 */
|
/** @private */
|
||||||
openDropdown: function(sb) {
|
openDropdown: function(sb) {
|
||||||
var st = window.getComputedStyle(sb, null),
|
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'),
|
fl = findParent(sb, '.cbi-value-field'),
|
||||||
sel = ul.querySelector('[selected]'),
|
sel = ul.querySelector('[selected]'),
|
||||||
rect = sb.getBoundingClientRect(),
|
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) {
|
document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) {
|
||||||
s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {}));
|
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.maxHeight = (vpHeight * 0.5) + 'px';
|
||||||
ul.style.WebkitOverflowScrolling = 'touch';
|
ul.style.WebkitOverflowScrolling = 'touch';
|
||||||
|
|
||||||
var getScrollParent = function(element) {
|
var scrollFrom = scrollParent.scrollTop,
|
||||||
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,
|
|
||||||
scrollTo = scrollFrom + rect.top - vpHeight * 0.5;
|
scrollTo = scrollFrom + rect.top - vpHeight * 0.5;
|
||||||
|
|
||||||
var scrollStep = function(timestamp) {
|
var scrollStep = function(timestamp) {
|
||||||
|
@ -1282,10 +1283,11 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
|
||||||
ul.style.top = ul.style.bottom = '';
|
ul.style.top = ul.style.bottom = '';
|
||||||
|
|
||||||
window.requestAnimationFrame(function() {
|
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,
|
fullHeight = 0,
|
||||||
spaceAbove = rect.top,
|
spaceAbove = rect.top - containerRect.top,
|
||||||
spaceBelow = window.innerHeight - rect.height - rect.top;
|
spaceBelow = containerRect.bottom - rect.bottom;
|
||||||
|
|
||||||
for (var i = 0; i < (items == -1 ? li.length : items); i++)
|
for (var i = 0; i < (items == -1 ? li.length : items); i++)
|
||||||
fullHeight += li[i].getBoundingClientRect().height;
|
fullHeight += li[i].getBoundingClientRect().height;
|
||||||
|
|
Loading…
Reference in a new issue