diff options
Diffstat (limited to 'modules/luci-base/htdocs/luci-static/resources')
-rw-r--r-- | modules/luci-base/htdocs/luci-static/resources/form.js | 15 | ||||
-rw-r--r-- | modules/luci-base/htdocs/luci-static/resources/ui.js | 84 |
2 files changed, 76 insertions, 23 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 3c538b88ca..317b49fdfe 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -281,7 +281,7 @@ var CBIAbstractElement = baseclass.extend(/** @lends LuCI.form.AbstractElement.p * The input string to clean. * * @returns {string} - * The cleaned input string with HTML removes removed. + * The cleaned input string with HTML tags removed. */ stripTags: function(s) { if (typeof(s) == 'string' && !s.match(/[<>]/)) @@ -3211,8 +3211,17 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p return (stackedMap ? activeMap.save(null, true) : Promise.resolve()).then(L.bind(function() { section_id = sref['.name']; - var m = new CBIMap(parent.config, null, null), - s = m.section(CBINamedSection, section_id, this.sectiontype); + var m; + + if (parent instanceof CBIJSONMap) { + m = new CBIJSONMap(null, null, null); + m.data = parent.data; + } + else { + m = new CBIMap(parent.config, null, null); + } + + var s = m.section(CBINamedSection, section_id, this.sectiontype); m.parent = parent; m.section = section_id; diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index c7b7ccd773..51b6c0902d 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -1050,7 +1050,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { 'class': 'cbi-dropdown', 'multiple': this.options.multiple ? '' : null, 'optional': this.options.optional ? '' : null, - 'disabled': this.options.disabled ? '' : null + 'disabled': this.options.disabled ? '' : null, + 'tabindex': -1 }, E('ul')); var keys = Object.keys(this.choices); @@ -1186,11 +1187,11 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { } else { sb.addEventListener('mouseover', this.handleMouseover.bind(this)); + sb.addEventListener('mouseout', this.handleMouseout.bind(this)); sb.addEventListener('focus', this.handleFocus.bind(this)); canary.addEventListener('focus', this.handleCanaryFocus.bind(this)); - window.addEventListener('mouseover', this.setFocus); window.addEventListener('click', this.closeAllDropdowns); } @@ -1343,7 +1344,12 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { sb.lastElementChild.setAttribute('tabindex', 0); - this.setFocus(sb, sel || li[0], true); + var focusFn = L.bind(function(el) { + this.setFocus(sb, el, true); + ul.removeEventListener('transitionend', focusFn); + }, this, sel || li[0]); + + ul.addEventListener('transitionend', focusFn); }, /** @private */ @@ -1559,26 +1565,33 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { /** @private */ setFocus: function(sb, elem, scroll) { - if (sb && sb.hasAttribute && sb.hasAttribute('locked-in')) + if (sb.hasAttribute('locked-in')) return; - if (sb.target && findParent(sb.target, 'ul.dropdown')) + sb.querySelectorAll('.focus').forEach(function(e) { + e.classList.remove('focus'); + }); + + elem.classList.add('focus'); + + if (scroll) + elem.parentNode.scrollTop = elem.offsetTop - elem.parentNode.offsetTop; + + elem.focus(); + }, + + /** @private */ + handleMouseout: function(ev) { + var sb = ev.currentTarget; + + if (!sb.hasAttribute('open')) return; - document.querySelectorAll('.focus').forEach(function(e) { - if (!matchesElem(e, 'input')) { - e.classList.remove('focus'); - e.blur(); - } + sb.querySelectorAll('.focus').forEach(function(e) { + e.classList.remove('focus'); }); - if (elem) { - elem.focus(); - elem.classList.add('focus'); - - if (scroll) - elem.parentNode.scrollTop = elem.offsetTop - elem.parentNode.offsetTop; - } + sb.querySelector('ul.dropdown').focus(); }, /** @private */ @@ -1758,7 +1771,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { /** @private */ handleKeydown: function(ev) { - var sb = ev.currentTarget; + var sb = ev.currentTarget, + ul = sb.querySelector('ul.dropdown'); if (matchesElem(ev.target, 'input')) return; @@ -1779,6 +1793,7 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { switch (ev.keyCode) { case 27: this.closeDropdown(sb); + ev.stopPropagation(); break; case 13: @@ -1802,6 +1817,10 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { this.setFocus(sb, active.previousElementSibling); ev.preventDefault(); } + else if (document.activeElement === ul) { + this.setFocus(sb, ul.lastElementChild); + ev.preventDefault(); + } break; case 40: @@ -1809,6 +1828,10 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { this.setFocus(sb, active.nextElementSibling); ev.preventDefault(); } + else if (document.activeElement === ul) { + this.setFocus(sb, ul.firstElementChild); + ev.preventDefault(); + } break; } } @@ -3463,8 +3486,17 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ { var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ { __init__: function() { modalDiv = document.body.appendChild( - dom.create('div', { id: 'modal_overlay' }, - dom.create('div', { class: 'modal', role: 'dialog', 'aria-modal': true }))); + dom.create('div', { + id: 'modal_overlay', + tabindex: -1, + keydown: this.cancelModal + }, [ + dom.create('div', { + class: 'modal', + role: 'dialog', + 'aria-modal': true + }) + ])); tooltipDiv = document.body.appendChild( dom.create('div', { class: 'cbi-tooltip' })); @@ -3528,6 +3560,7 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ { document.body.classList.add('modal-overlay-active'); modalDiv.scrollTop = 0; + modalDiv.focus(); return dlg; }, @@ -3544,6 +3577,17 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ { */ hideModal: function() { document.body.classList.remove('modal-overlay-active'); + modalDiv.blur(); + }, + + /** @private */ + cancelModal: function(ev) { + if (ev.key == 'Escape') { + var btn = modalDiv.querySelector('.right > button, .right > .btn'); + + if (btn) + btn.click(); + } }, /** @private */ |