This commit is contained in:
2021-10-03 20:06:12 +03:00
parent dee5c19f48
commit a0a6a9b710
11 changed files with 459 additions and 168 deletions
+122 -77
View File
@@ -1,11 +1,11 @@
/** @module menu */
//todo: instance, options, auto-options-by-node, fast reCalc, fast reInit, userEventManager, collection
//todo: instance, options, auto-options-by-node, userEventManager
__PluginManager__.register('menu',function(module, exports, require) {
var align = require('align');
var libModule = require('lib');
var utils = require('utils');
var dataStructures = require('dataStructures');
/**
* @class kitMenuClassDefaultOptions
@@ -120,19 +120,20 @@ __PluginManager__.register('menu',function(module, exports, require) {
}
this.addAnimation();
};
Menu.prototype.hide = function () {
getChainActiveMenuDataList(this.id).reverse().forEach(function (data) {
data.menu.hideNodeNow();
});
return this;
};
Menu.prototype.hideNode = function () {
// console.log('Menu: hideNode');
this.hideNodeDeferred();
this.hideNodeNow();
};
Menu.prototype.hideNodeDeferred = function () {
this.deferredHideCancel();
this.deferredHideID = setTimeout(this.hideNodeNow.bind(this), this.options.hideDelay);
// console.log('hideNodeDeferred ' + this.deferredHideID);
};
/**
* @returns {Menu}
*/
Menu.prototype.deferredHideCancel = function () {
if(this.deferredHideID) {
clearTimeout(this.deferredHideID);
@@ -140,10 +141,6 @@ __PluginManager__.register('menu',function(module, exports, require) {
}
return this;
};
/**
* @returns {Menu}
*/
Menu.prototype.hideNodeNow = function () {
// console.log('Menu: hideNodeNow');
this.deferredHideCancel();
@@ -167,18 +164,7 @@ __PluginManager__.register('menu',function(module, exports, require) {
}
};
/**
* @returns {Menu}
*/
Menu.prototype.hide = function () {
this.hideNodeNow();
var tmp = this;
while(tmp instanceof MenuClass) {
tmp = tmp.hideNodeNow().getParentMenu();
}
return this;
};
Menu.prototype.calcStyle = function (recursive = false) {
Menu.prototype.calcStyle = function () {
// console.log('calcStyle ' + this.id);
if(!(this.options.parent instanceof Element)) {
console.warn('Menu.options.parent NOT instanceof Element');
@@ -208,33 +194,12 @@ __PluginManager__.register('menu',function(module, exports, require) {
.setHorizontal(hDirection, hAlign)
.setVertical('bottom', 'top');
if(recursive) {
this.calcStyleChildMenu(true, MenuList);
}
};
Menu.prototype.calcStyleChildMenu = function(recursive = false, MenuList = null){
var i, MenuListActive = [];
for(i in MenuList){
if(!MenuList.hasOwnProperty(i) || !(MenuList[i] instanceof Menu)) {
continue;
}
if(MenuList[i].bActive && this !== MenuList[i]) {
MenuListActive.push(MenuList[i]);
}
}
for(i in MenuListActive){
if(MenuListActive[i].getParentMenu() === this) {
MenuListActive[i].calcStyle();
if(recursive) {
MenuListActive[i].calcStyleChildMenu(true, MenuListActive);
}
}
}
Menu.prototype.calcStyleChain = function(){
getChainActiveMenuDataList(this.id).forEach(function (data) {
data.menu.calcStyle();
})
};
/**
@@ -389,10 +354,6 @@ __PluginManager__.register('menu',function(module, exports, require) {
this.node.removeEventListener('mouseenter', this.nodeActionHandler, false);
this.node.removeEventListener('mouseleave', this.nodeActionHandler, false);
};
Menu.prototype.toggleParent = function() {
this.node.classList.toggle('active');
return this.node.classList.contains('active');
};
Menu.prototype.insertToNode = function (parent) {
if(!(parent instanceof Element)) {
console.warn('Menu.insertToNode - node NOT instanceof Element');
@@ -435,14 +396,19 @@ __PluginManager__.register('menu',function(module, exports, require) {
//this.removeAnimation();
if(this.node.parentElement !== this.options.parent) {
this.removeAnimation();
this.node.remove();
this.options.parent.prepend(this.getNode());
this.options.parent.prepend(this.node);
}
this.render();
if(this.bActive) {
this.calcStyle(recursiveCalcStyle);
if(recursiveCalcStyle) {
this.calcStyleChain();
} else {
this.calcStyle();
}
this.showNode();
} else {
this.hideNode();
@@ -455,10 +421,10 @@ __PluginManager__.register('menu',function(module, exports, require) {
Menu.prototype.toggle = function() {
if(this.toggleParent()) {
if(this.node.classList.toggle('active')) {
this.showNode();
} else {
this.hideNode();
this.hide();
}
};
Menu.prototype.parentAction = function (event) {
@@ -467,7 +433,7 @@ __PluginManager__.register('menu',function(module, exports, require) {
switch (event.type) {
case 'mouseout':
if (this.needHideByParent(event.relatedTarget)) {
this.hideNode();
this.hideNodeDeferred();
}
break;
case 'mouseover':
@@ -488,7 +454,7 @@ __PluginManager__.register('menu',function(module, exports, require) {
break;
case 'mouseleave':
if(this.options.eventType === 'hover') {
this.hideNode();
this.hideNodeDeferred();
}
break;
case 'mouseenter':
@@ -842,32 +808,109 @@ __PluginManager__.register('menu',function(module, exports, require) {
}
return new MenuClass(options, items);
};
var getActiveMenuIdList = function(){
var getActiveMenuDataList = function(){
function valueEx(value) {
if(typeof value === 'function') {
return value();
}
return value;
}
var idList = [];
MenuList.forEach(function(element, index, array){
var dataList = [];
var refList = [];
function getParentId(id, element) {
if(!element) {
element = MenuList[id];
}
var parentId = false, parentMenu;
if(!(refList.hasOwnProperty(id) && refList[id].parentMenu)) {
if(element) {
refList[id] = refList[id] || {};
parentMenu = refList[id].parentMenu = element.getParentMenu();
}
parentMenu && (parentId = parentMenu.id);
return parentId;
}
return refList[id].parentMenu.id;
}
MenuList.forEach(function(element){
var pos, posId, id, parentId;
if((element instanceof MenuClass) && element.bInit && element.bActive) {
id = element.id;
parentId = false;
element.getParentMenu() && (parentId = element.getParentMenu().id);
!(parentId!==false&&(((pos=idList.indexOf(parentId))!==-1)?((idList.indexOf(id)===-1)&&idList.splice(pos
+1,0,id)):(((posId=idList.indexOf(id))!==-1)?idList.splice(posId,0,parentId):(idList.push(parentId),
idList.push(id))),0))&&(idList.indexOf(id)===-1)&&(idList.push(id));
if(!((element instanceof MenuClass) && element.bInit && element.bActive)) {
return;
}
id = element.id;
refList[id] = refList[id] || {};
refList[id].menu = element;
parentId = getParentId(id, element);
var depth = function (id){
return function() {
return 1 + valueEx(refList[refList[id].data.parentId].data.depth)
};
};
!(
parentId!==false
&&
(
((pos=idList.indexOf(parentId))!==-1)
?
(
(idList.indexOf(id)===-1)&&(idList.splice(pos+1,0,id), dataList.splice(pos+1,0, refList[id].data = {id:id, depth: depth(id), parentId: parentId, type: 1}))
)
:
(
(
refList[parentId] = refList[parentId] || {},
(posId=idList.indexOf(id))!==-1
)?
(
idList.splice(posId,0,parentId),
dataList.splice(posId,0,refList[parentId].data = {id:parentId, depth: depth(parentId), parentId: getParentId(parentId), type: 5})
):
(
idList.push(parentId),
dataList.push(refList[parentId].data = {id:parentId, depth: depth(parentId), parentId: getParentId(parentId), type: 2}),
idList.push(id),
dataList.push(refList[id].data = {id:id, depth: depth(id), parentId: parentId, type: 3})
)
),
0
)
)
&&(idList.indexOf(id)===-1)&&(idList.push(id), dataList.push(refList[id].data = {id:id, depth: 1, parentId: 0, type: 4}));
});
dataList.forEach(function (data) {
data.depth = valueEx(data.depth);
data.menu = refList[data.id].menu;
});
return dataList;
};
var getChainActiveMenuDataList = function (id) {
var dataList = getActiveMenuDataList(), result = [], depth = 0;
dataList.forEach(function(data) {
if(data.id === id) {
depth = data.depth;
}
if(depth === data.depth && data.id !== id) {
depth = 0;
}
if(depth) {
result.push(data);
}
});
return idList
return result;
};
var reInitAllMenu = function(){
var idList = getActiveMenuIdList();
idList.forEach(function(id, i, arr) {
MenuList[id].reInit();
var dataList = getActiveMenuDataList();
dataList.forEach(function(data) {
data.menu.reInit();
});
};
var reCalcAllMenu = function(){
console.log('reCalcAllMenu');
var idList = getActiveMenuIdList();
idList.forEach(function(id, i, arr) {
MenuList[id].calcStyle();
var dataList = getActiveMenuDataList();
dataList.forEach(function(data) {
data.menu.calcStyle();
});
};
var autoload = function(doc = document, selector = '.kit-menu'){
@@ -884,7 +927,7 @@ __PluginManager__.register('menu',function(module, exports, require) {
);
};
var reCalcAllMenuLimiter = new utils.StackExecutionLimiter(this, reCalcAllMenu, 200);
var reCalcAllMenuLimiter = new dataStructures.StackExecutionLimiter(this, reCalcAllMenu, 250);
var globalHandlers = {
resize: function(){
reCalcAllMenuLimiter.exec();
@@ -903,6 +946,8 @@ __PluginManager__.register('menu',function(module, exports, require) {
reInitAllMenu: reInitAllMenu,
reCalcAllMenu: reCalcAllMenu,
autoload: autoload,
getActiveMenuDataList: getActiveMenuDataList,
getChainActiveMenuDataList: getChainActiveMenuDataList,
MenuList: MenuList,
};