2014-08-20 22:58:54 +02:00
|
|
|
/**
|
2017-01-11 16:24:33 +01:00
|
|
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
2014-08-20 22:58:54 +02:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
**/
|
|
|
|
RED.menu = (function() {
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
var menuItems = {};
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
function createMenuItem(opt) {
|
|
|
|
var item;
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2015-04-13 14:55:17 +02:00
|
|
|
if (opt !== null && opt.id) {
|
|
|
|
var themeSetting = RED.settings.theme("menu."+opt.id);
|
|
|
|
if (themeSetting === false) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2015-04-20 12:17:27 +02:00
|
|
|
function setInitialState() {
|
2017-04-28 21:49:01 +02:00
|
|
|
var savedStateActive = RED.settings.get("menu-" + opt.id);
|
|
|
|
if (opt.setting) {
|
|
|
|
// May need to migrate pre-0.17 setting
|
|
|
|
|
|
|
|
if (savedStateActive !== null) {
|
|
|
|
RED.settings.set(opt.setting,savedStateActive);
|
|
|
|
RED.settings.remove("menu-" + opt.id);
|
|
|
|
} else {
|
|
|
|
savedStateActive = RED.settings.get(opt.setting);
|
|
|
|
}
|
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
if (savedStateActive) {
|
|
|
|
link.addClass("active");
|
2016-12-04 23:59:43 +01:00
|
|
|
triggerAction(opt.id,true);
|
2014-10-30 15:19:44 +01:00
|
|
|
} else if (savedStateActive === false) {
|
|
|
|
link.removeClass("active");
|
2016-12-04 23:59:43 +01:00
|
|
|
triggerAction(opt.id,false);
|
2014-10-30 15:19:44 +01:00
|
|
|
} else if (opt.hasOwnProperty("selected")) {
|
|
|
|
if (opt.selected) {
|
|
|
|
link.addClass("active");
|
|
|
|
} else {
|
|
|
|
link.removeClass("active");
|
|
|
|
}
|
2016-12-04 23:59:43 +01:00
|
|
|
triggerAction(opt.id,opt.selected);
|
2014-10-30 15:19:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
if (opt === null) {
|
|
|
|
item = $('<li class="divider"></li>');
|
|
|
|
} else {
|
|
|
|
item = $('<li></li>');
|
2015-07-09 17:48:53 +02:00
|
|
|
|
|
|
|
if (opt.group) {
|
|
|
|
item.addClass("menu-group-"+opt.group);
|
|
|
|
|
|
|
|
}
|
2015-01-15 22:41:40 +01:00
|
|
|
var linkContent = '<a '+(opt.id?'id="'+opt.id+'" ':'')+'tabindex="-1" href="#">';
|
|
|
|
if (opt.toggle) {
|
|
|
|
linkContent += '<i class="fa fa-square pull-left"></i>';
|
|
|
|
linkContent += '<i class="fa fa-check-square pull-left"></i>';
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2015-01-15 22:41:40 +01:00
|
|
|
}
|
2015-01-14 23:40:45 +01:00
|
|
|
if (opt.icon !== undefined) {
|
|
|
|
if (/\.png/.test(opt.icon)) {
|
|
|
|
linkContent += '<img src="'+opt.icon+'"/> ';
|
|
|
|
} else {
|
|
|
|
linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> ';
|
|
|
|
}
|
|
|
|
}
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2015-01-14 23:40:45 +01:00
|
|
|
if (opt.sublabel) {
|
|
|
|
linkContent += '<span class="menu-label-container"><span class="menu-label">'+opt.label+'</span>'+
|
|
|
|
'<span class="menu-sublabel">'+opt.sublabel+'</span></span>'
|
|
|
|
} else {
|
|
|
|
linkContent += '<span class="menu-label">'+opt.label+'</span>'
|
|
|
|
}
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2015-01-14 23:40:45 +01:00
|
|
|
linkContent += '</a>';
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2015-01-14 23:40:45 +01:00
|
|
|
var link = $(linkContent).appendTo(item);
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
menuItems[opt.id] = opt;
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
if (opt.onselect) {
|
2017-05-12 23:12:55 +02:00
|
|
|
link.click(function(e) {
|
|
|
|
e.preventDefault();
|
2014-02-25 00:35:11 +01:00
|
|
|
if ($(this).parent().hasClass("disabled")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (opt.toggle) {
|
2015-01-14 23:40:45 +01:00
|
|
|
var selected = isSelected(opt.id);
|
|
|
|
if (typeof opt.toggle === "string") {
|
|
|
|
if (!selected) {
|
|
|
|
for (var m in menuItems) {
|
|
|
|
if (menuItems.hasOwnProperty(m)) {
|
|
|
|
var mi = menuItems[m];
|
|
|
|
if (mi.id != opt.id && opt.toggle == mi.toggle) {
|
|
|
|
setSelected(mi.id,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setSelected(opt.id,true);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
setSelected(opt.id, !selected);
|
|
|
|
}
|
2014-02-25 00:35:11 +01:00
|
|
|
} else {
|
2016-12-04 23:59:43 +01:00
|
|
|
triggerAction(opt.id);
|
2014-02-25 00:35:11 +01:00
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
});
|
2016-12-04 23:59:43 +01:00
|
|
|
if (opt.toggle) {
|
|
|
|
setInitialState();
|
|
|
|
}
|
2014-08-20 22:58:54 +02:00
|
|
|
} else if (opt.href) {
|
|
|
|
link.attr("target","_blank").attr("href",opt.href);
|
2015-01-08 23:34:26 +01:00
|
|
|
} else if (!opt.options) {
|
|
|
|
item.addClass("disabled");
|
|
|
|
link.click(function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
});
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
|
|
|
if (opt.options) {
|
|
|
|
item.addClass("dropdown-submenu pull-left");
|
|
|
|
var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item);
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
for (var i=0;i<opt.options.length;i++) {
|
2015-04-13 14:55:17 +02:00
|
|
|
var li = createMenuItem(opt.options[i]);
|
|
|
|
if (li) {
|
|
|
|
li.appendTo(submenu);
|
|
|
|
}
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (opt.disabled) {
|
|
|
|
item.addClass("disabled");
|
|
|
|
}
|
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
return item;
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
|
|
|
function createMenu(options) {
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2017-05-12 23:12:55 +02:00
|
|
|
var menuParent = $("#"+options.id);
|
2014-11-12 14:21:39 +01:00
|
|
|
|
2017-05-12 23:12:55 +02:00
|
|
|
var topMenu = $("<ul/>",{id:options.id+"-submenu", class:"dropdown-menu pull-right"});
|
2015-07-09 17:48:53 +02:00
|
|
|
|
2017-05-12 23:12:55 +02:00
|
|
|
if (menuParent.length === 1) {
|
|
|
|
topMenu.insertAfter(menuParent);
|
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2015-04-13 14:55:17 +02:00
|
|
|
var lastAddedSeparator = false;
|
2014-08-20 22:58:54 +02:00
|
|
|
for (var i=0;i<options.options.length;i++) {
|
|
|
|
var opt = options.options[i];
|
2015-04-13 14:55:17 +02:00
|
|
|
if (opt !== null || !lastAddedSeparator) {
|
|
|
|
var li = createMenuItem(opt);
|
|
|
|
if (li) {
|
|
|
|
li.appendTo(topMenu);
|
|
|
|
lastAddedSeparator = (opt === null);
|
|
|
|
}
|
|
|
|
}
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
2017-05-12 23:12:55 +02:00
|
|
|
|
|
|
|
return topMenu;
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2016-12-04 23:59:43 +01:00
|
|
|
function triggerAction(id, args) {
|
|
|
|
var opt = menuItems[id];
|
|
|
|
var callback = opt.onselect;
|
|
|
|
if (typeof opt.onselect === 'string') {
|
|
|
|
callback = RED.actions.get(opt.onselect);
|
|
|
|
}
|
|
|
|
if (callback) {
|
|
|
|
callback.call(opt,args);
|
|
|
|
} else {
|
|
|
|
console.log("No callback for",id,opt.onselect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
function isSelected(id) {
|
2014-10-30 15:19:44 +01:00
|
|
|
return $("#" + id).hasClass("active");
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
function setSelected(id,state) {
|
|
|
|
if (isSelected(id) == state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var opt = menuItems[id];
|
|
|
|
if (state) {
|
|
|
|
$("#"+id).addClass("active");
|
|
|
|
} else {
|
|
|
|
$("#"+id).removeClass("active");
|
|
|
|
}
|
2015-04-13 14:55:17 +02:00
|
|
|
if (opt && opt.onselect) {
|
2016-12-04 23:59:43 +01:00
|
|
|
triggerAction(opt.id,state);
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
2017-04-28 21:49:01 +02:00
|
|
|
RED.settings.set(opt.setting||("menu-"+opt.id), state);
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2016-12-04 23:59:43 +01:00
|
|
|
function toggleSelected(id) {
|
|
|
|
setSelected(id,!isSelected(id));
|
|
|
|
}
|
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
function setDisabled(id,state) {
|
|
|
|
if (state) {
|
|
|
|
$("#"+id).parent().addClass("disabled");
|
|
|
|
} else {
|
|
|
|
$("#"+id).parent().removeClass("disabled");
|
|
|
|
}
|
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
function addItem(id,opt) {
|
2015-07-09 17:48:53 +02:00
|
|
|
var item = createMenuItem(opt);
|
|
|
|
if (opt.group) {
|
|
|
|
var groupItems = $("#"+id+"-submenu").children(".menu-group-"+opt.group);
|
|
|
|
if (groupItems.length === 0) {
|
|
|
|
item.appendTo("#"+id+"-submenu");
|
|
|
|
} else {
|
|
|
|
for (var i=0;i<groupItems.length;i++) {
|
|
|
|
var groupItem = groupItems[i];
|
|
|
|
var label = $(groupItem).find(".menu-label").html();
|
|
|
|
if (opt.label < label) {
|
|
|
|
$(groupItem).before(item);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i === groupItems.length) {
|
|
|
|
item.appendTo("#"+id+"-submenu");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
item.appendTo("#"+id+"-submenu");
|
|
|
|
}
|
2014-08-20 22:58:54 +02:00
|
|
|
}
|
|
|
|
function removeItem(id) {
|
|
|
|
$("#"+id).parent().remove();
|
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-02-25 00:35:11 +01:00
|
|
|
function setAction(id,action) {
|
2015-04-13 14:55:17 +02:00
|
|
|
var opt = menuItems[id];
|
|
|
|
if (opt) {
|
|
|
|
opt.onselect = action;
|
|
|
|
}
|
2014-02-25 00:35:11 +01:00
|
|
|
}
|
2014-10-30 15:19:44 +01:00
|
|
|
|
2014-08-20 22:58:54 +02:00
|
|
|
return {
|
|
|
|
init: createMenu,
|
|
|
|
setSelected: setSelected,
|
|
|
|
isSelected: isSelected,
|
2016-12-04 23:59:43 +01:00
|
|
|
toggleSelected: toggleSelected,
|
2014-08-20 22:58:54 +02:00
|
|
|
setDisabled: setDisabled,
|
|
|
|
addItem: addItem,
|
2014-02-25 00:35:11 +01:00
|
|
|
removeItem: removeItem,
|
|
|
|
setAction: setAction
|
2014-08-20 22:58:54 +02:00
|
|
|
//TODO: add an api for replacing a submenu - see library.js:loadFlowLibrary
|
|
|
|
}
|
|
|
|
})();
|