summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base/htdocs/luci-static/resources/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-base/htdocs/luci-static/resources/ui.js')
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/ui.js77
1 files changed, 37 insertions, 40 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js
index df66f2bb1d..a4f002591d 100644
--- a/modules/luci-base/htdocs/luci-static/resources/ui.js
+++ b/modules/luci-base/htdocs/luci-static/resources/ui.js
@@ -222,7 +222,7 @@ var UIElement = baseclass.extend(/** @lends LuCI.ui.AbstractElement.prototype */
},
/**
- * Setup listeners for native DOM events that may update the widget value.
+ * Set up listeners for native DOM events that may update the widget value.
*
* Sets up event handlers on the given target DOM node for the given event
* names which may cause the input value to update, such as `keyup` or
@@ -265,7 +265,7 @@ var UIElement = baseclass.extend(/** @lends LuCI.ui.AbstractElement.prototype */
},
/**
- * Setup listeners for native DOM events that may change the widget value.
+ * Set up listeners for native DOM events that may change the widget value.
*
* Sets up event handlers on the given target DOM node for the given event
* names which may cause the input value to change completely, such as
@@ -292,7 +292,7 @@ var UIElement = baseclass.extend(/** @lends LuCI.ui.AbstractElement.prototype */
},
/**
- * Render the widget, setup event listeners and return resulting markup.
+ * Render the widget, set up event listeners and return resulting markup.
*
* @instance
* @memberof LuCI.ui.AbstractElement
@@ -1187,8 +1187,6 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
window.addEventListener('touchstart', this.closeAllDropdowns);
}
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));
@@ -1340,7 +1338,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
sb.insertBefore(pv, ul.nextElementSibling);
li.forEach(function(l) {
- l.setAttribute('tabindex', 0);
+ if (!l.hasAttribute('unselectable'))
+ l.setAttribute('tabindex', 0);
});
sb.lastElementChild.setAttribute('tabindex', 0);
@@ -1459,7 +1458,7 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
li.setAttribute('display', 0);
li.setAttribute('selected', '');
- this.closeDropdown(sb, true);
+ this.closeDropdown(sb);
}
this.saveValues(sb, ul);
@@ -1582,20 +1581,6 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
},
/** @private */
- handleMouseout: function(ev) {
- var sb = ev.currentTarget;
-
- if (!sb.hasAttribute('open'))
- return;
-
- sb.querySelectorAll('.focus').forEach(function(e) {
- e.classList.remove('focus');
- });
-
- sb.querySelector('ul.dropdown').focus();
- },
-
- /** @private */
createChoiceElement: function(sb, value, label) {
var tpl = sb.querySelector(this.options.create_template),
markup = null;
@@ -1620,6 +1605,9 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
if (this.options.multiple)
this.transformItem(sb, new_item);
+ if (!new_item.hasAttribute('unselectable'))
+ new_item.setAttribute('tabindex', 0);
+
return new_item;
},
@@ -1826,7 +1814,12 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
case 40:
if (active && active.nextElementSibling) {
- this.setFocus(sb, active.nextElementSibling);
+ var li = active.nextElementSibling;
+ this.setFocus(sb, li);
+ if (this.options.create && li == li.parentNode.lastElementChild) {
+ var input = li.querySelector('input:not([type="hidden"]):not([type="checkbox"]');
+ if (input) input.focus();
+ }
ev.preventDefault();
}
else if (document.activeElement === ul) {
@@ -1858,19 +1851,6 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
},
/** @private */
- handleMouseover: function(ev) {
- var sb = ev.currentTarget;
-
- if (!sb.hasAttribute('open'))
- return;
-
- var li = findParent(ev.target, 'li');
-
- if (li && li.parentNode.classList.contains('dropdown'))
- this.setFocus(sb, li);
- },
-
- /** @private */
handleFocus: function(ev) {
var sb = ev.currentTarget;
@@ -1888,7 +1868,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
/** @private */
handleCreateKeydown: function(ev) {
var input = ev.currentTarget,
- sb = findParent(input, '.cbi-dropdown');
+ li = findParent(input, 'li'),
+ sb = findParent(li, '.cbi-dropdown');
switch (ev.keyCode) {
case 13:
@@ -1897,9 +1878,23 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
if (input.classList.contains('cbi-input-invalid'))
return;
+ this.handleCreateBlur(ev);
this.createItems(sb, input.value);
input.value = '';
- input.blur();
+ break;
+
+ case 27:
+ this.handleCreateBlur(ev);
+ this.closeDropdown(sb);
+ ev.stopPropagation();
+ input.value = '';
+ break;
+
+ case 38:
+ if (li.previousElementSibling) {
+ this.handleCreateBlur(ev);
+ this.setFocus(sb, li.previousElementSibling, true);
+ }
break;
}
},
@@ -1907,13 +1902,15 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ {
/** @private */
handleCreateFocus: function(ev) {
var input = ev.currentTarget,
- cbox = findParent(input, 'li').querySelector('input[type="checkbox"]'),
+ li = findParent(input, 'li'),
+ cbox = li.querySelector('input[type="checkbox"]'),
sb = findParent(input, '.cbi-dropdown');
if (cbox)
cbox.checked = true;
sb.setAttribute('locked-in', '');
+ this.setFocus(sb, li, true);
},
/** @private */
@@ -3509,7 +3506,7 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
tooltipDiv = document.body.appendChild(
dom.create('div', { class: 'cbi-tooltip' }));
- /* setup old aliases */
+ /* set up old aliases */
L.showModal = this.showModal;
L.hideModal = this.hideModal;
L.showTooltip = this.showTooltip;
@@ -3580,7 +3577,7 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
* behaviour. It has no effect if no modal dialog is currently open.
*
* Note that this function is stand-alone, it does not rely on `this` and
- * will not invoke other class functions so it suitable to be used as event
+ * will not invoke other class functions so it is suitable to be used as event
* handler as-is without the need to bind it first.
*/
hideModal: function() {