summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-12-02 12:36:03 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-12-02 12:36:03 +0000
commitb2a7b2497806ac300b24a618279bd08a072903c2 (patch)
treed844929af037693d38b051a2a6982d9ff9cdb972
parent83c12d548cd3c69e94884ca264af37db680ae950 (diff)
themes/base: implement close delay for popup menus (#95)
-rw-r--r--themes/base/htdocs/luci-static/resources/Dropdowns.js122
1 files changed, 98 insertions, 24 deletions
diff --git a/themes/base/htdocs/luci-static/resources/Dropdowns.js b/themes/base/htdocs/luci-static/resources/Dropdowns.js
index ff2f0e665..8c07a6f2f 100644
--- a/themes/base/htdocs/luci-static/resources/Dropdowns.js
+++ b/themes/base/htdocs/luci-static/resources/Dropdowns.js
@@ -60,46 +60,118 @@ function initDropdowns() {
}
}
- function onmouseover(evt) {
- XHTML1.addClass(evt.currentTarget, "over");
- if( isIE6 ) hideSelects();
+ function isEmptyObject(obj) {
+ for(var i in obj) {
+ return false;
+ }
+ return true;
}
- function onmouseout(evt) {
- XHTML1.removeClass(evt.currentTarget, "over");
- if( isIE6 ) showSelects();
+ var nextUniqueID = 1;
+ var elementsNeeded = {};
+ var menusShown = {};
+ var menusToHide = {};
+ var delayHideTimerId;
+ var delayHideAllTime = 1000;
+ var delayHideTime = 400;
+ function delayHide() {
+ for(var i in menusToHide) {
+ XHTML1.removeClass(menusToHide[i], "focus");
+ }
+ delayHideTimerId = null;
}
- function onfocus(evt) {
- for(var element = evt.currentTarget; element; element = element.parentNode) {
- if(XHTML1.isElement(element, "li")) {
+ function updatePopup() {
+ if(isIE6) {
+ if(isEmptyObject(elementsNeeded)) {
+ showSelects();
+ }
+ else{
+ hideSelects();
+ }
+ }
+
+ var menusShownOld = menusShown;
+ menusShown = {};
+ for(var id in elementsNeeded) {
+ var element = elementsNeeded[id];
+ for(element = findLi(element); element; element = findLi(element.parentNode)) {
XHTML1.addClass(element, "focus");
+ if(!element.uniqueID) {
+ element.uniqueID = nextUniqueID++;
+ }
+ element.style.zIndex = 1000;
+ menusShown[element.uniqueID] = element;
+ delete menusToHide[element.uniqueID];
+ }
+ }
+ for(var id in menusShownOld) {
+ if(!menusShown[id]) {
+ if(delayHideTimerId) {
+ clearTimeout(delayHideTimerId);
+ delayHideTimerId = 0;
+ delayHide();
+ }
+ menusToHide[id] = menusShownOld[id];
+ menusToHide[id].style.zIndex = 999;
+ }
+ }
+ if(menusToHide || isEmptyObject(elementsNeeded)) {
+ if(delayHideTimerId) {
+ clearTimeout(delayHideTimerId);
}
+ delayHideTimerId = setTimeout(delayHide, isEmptyObject(elementsNeeded) ? delayHideAllTime : delayHideTime);
}
- if( isIE6 ) hideSelects();
}
- function onblur(evt) {
- for(var element = evt.currentTarget; element; element = element.parentNode) {
+ function findLi(element) {
+ for(; element; element = element.parentNode) {
if(XHTML1.isElement(element, "li")) {
- XHTML1.removeClass(element, "focus");
+ return element;
}
}
- if( isIE6 ) showSelects();
}
- if(document.all) {
- var liElements = XHTML1.getElementsByTagName("li");
- for(var i = 0; i < liElements.length; i++) {
- var li = liElements[i];
- for(var element = li.parentNode; element; element = element.parentNode) {
- if(XHTML1.isElement(element, "ul") && XHTML1.containsClass(element, "dropdowns")) {
- XHTML1.addEventListener(li, "mouseover", onmouseover);
- XHTML1.addEventListener(li, "mouseout", onmouseout);
- break;
- }
+ function onmouseover(evt) {
+ var li = findLi(evt.currentTarget);
+ if(li && !li.focused) {
+ if(!li.uniqueID) {
+ li.uniqueID = nextUniqueID++;
+ }
+ elementsNeeded[li.uniqueID] = li;
+ }
+ XHTML1.addClass(evt.currentTarget, "over");
+ updatePopup();
+ }
+
+ function onmouseout(evt) {
+ var li = findLi(evt.currentTarget);
+ if(li && !li.focused && li.uniqueID) {
+ delete elementsNeeded[li.uniqueID];
+ }
+ XHTML1.removeClass(evt.currentTarget, "over");
+ updatePopup();
+ }
+
+ function onfocus(evt) {
+ var li = findLi(evt.currentTarget);
+ if(li) {
+ li.focused = true;
+ if(!li.uniqueID) {
+ li.uniqueID = nextUniqueID++;
}
+ elementsNeeded[li.uniqueID] = li;
+ }
+ updatePopup();
+ }
+
+ function onblur(evt) {
+ var li = findLi(evt.currentTarget);
+ if(li) {
+ li.focused = false;
+ delete elementsNeeded[li.uniqueID];
}
+ updatePopup();
}
var aElements = XHTML1.getElementsByTagName("a");
@@ -109,6 +181,8 @@ function initDropdowns() {
if(XHTML1.isElement(element, "ul") && XHTML1.containsClass(element, "dropdowns")) {
XHTML1.addEventListener(a, "focus", onfocus);
XHTML1.addEventListener(a, "blur", onblur);
+ XHTML1.addEventListener(a, "mouseover", onmouseover);
+ XHTML1.addEventListener(a, "mouseout", onmouseout);
break;
}
}