541 lines
19 KiB
JavaScript
541 lines
19 KiB
JavaScript
/* Copyright 2005 - 2015 Annpoint, s.r.o.
|
|
Use of this software is subject to license terms.
|
|
http://www.daypilot.org/
|
|
*/
|
|
|
|
if (typeof DayPilot === 'undefined') {
|
|
var DayPilot = {};
|
|
}
|
|
|
|
if (typeof DayPilot.Global === 'undefined') {
|
|
DayPilot.Global = {};
|
|
}
|
|
|
|
// compatibility with 5.9.2029 and previous
|
|
if (typeof DayPilotMenu === 'undefined') {
|
|
var DayPilotMenu = DayPilot.MenuVisible = {};
|
|
}
|
|
|
|
(function() {
|
|
|
|
|
|
if (typeof DayPilot.Menu !== 'undefined') {
|
|
return;
|
|
}
|
|
|
|
var DayPilotMenu = {};
|
|
|
|
DayPilotMenu.mouse = null;
|
|
DayPilotMenu.menu = null;
|
|
DayPilotMenu.clickRegistered = false;
|
|
DayPilotMenu.hideTimeout = null;
|
|
|
|
DayPilot.Menu = function(items) {
|
|
var menu = this;
|
|
|
|
this.v = '1658';
|
|
this.zIndex = 10; // more than 10,001 used by ModalPopupExtender
|
|
this.useShadow = true;
|
|
this.cssClassPrefix = "menu_default";
|
|
this.cssOnly = true;
|
|
this.menuTitle = null;
|
|
this.showMenuTitle = false;
|
|
this.hideOnMouseOut = false;
|
|
|
|
// hiding internal properties for angular
|
|
this._state = function() {};
|
|
this._state.ref = null; // ref object, used for position
|
|
|
|
if (items && DayPilot.isArray(items)) {
|
|
this.items = items;
|
|
}
|
|
|
|
this.show = function(e, submenu) {
|
|
var value = null;
|
|
if (typeof e.id === 'string' || typeof e.id === 'number') {
|
|
value = e.id;
|
|
}
|
|
else if (typeof e.id === 'function') {
|
|
value = e.id();
|
|
}
|
|
else if (typeof e.value === 'function') {
|
|
value = e.value();
|
|
}
|
|
|
|
if (typeof(DayPilot.Bubble) !== 'undefined') { // hide any bubble if active
|
|
DayPilot.Bubble.hideActive();
|
|
}
|
|
|
|
if (!submenu) {
|
|
DayPilotMenu.menuClean();
|
|
}
|
|
|
|
// clear old data
|
|
this._state.submenu = null;
|
|
|
|
if (DayPilotMenu.mouse === null) { // not possible to execute before mouse move (TODO)
|
|
return;
|
|
}
|
|
|
|
if (!menu.cssOnly) {
|
|
menu.cssOnly = true;
|
|
DayPilot.Util.log("DayPilot: cssOnly = false mode is not supported since DayPilot Pro 8.0.");
|
|
}
|
|
|
|
|
|
var div = document.createElement("div");
|
|
div.style.position = "absolute";
|
|
div.style.top = "0px";
|
|
div.style.left = "0px";
|
|
div.style.display = 'none';
|
|
div.style.overflow = 'hidden';
|
|
div.style.zIndex = this.zIndex + 1;
|
|
div.className = this.applyCssClass('main');
|
|
div.onclick = function() {
|
|
this.parentNode.removeChild(this);
|
|
};
|
|
|
|
if (this.hideOnMouseOut) {
|
|
div.onmousemove = function(ev) {
|
|
clearTimeout(DayPilotMenu.hideTimeout);
|
|
};
|
|
div.onmouseout = function(ev) {
|
|
menu.delayedHide();
|
|
};
|
|
}
|
|
|
|
if (!this.items || this.items.length === 0) {
|
|
throw "No menu items defined.";
|
|
}
|
|
|
|
if (this.showMenuTitle) {
|
|
var title = document.createElement("div");
|
|
title.innerHTML = this.menuTitle;
|
|
title.className = this.applyCssClass("title");
|
|
div.appendChild(title);
|
|
}
|
|
|
|
for (var i = 0; i < this.items.length; i++) {
|
|
var mi = this.items[i];
|
|
var item = document.createElement("div");
|
|
//item.style.position = 'relative';
|
|
|
|
if (typeof mi === 'undefined') {
|
|
continue;
|
|
}
|
|
if (mi.text === '-') {
|
|
var separator = document.createElement("div");
|
|
item.appendChild(separator);
|
|
}
|
|
else {
|
|
var link = document.createElement("a");
|
|
link.style.position = 'relative';
|
|
link.style.display = "block";
|
|
if (mi.disabled) {
|
|
DayPilot.Util.addClass(link, menu.applyCssClass("item_disabled"));
|
|
}
|
|
else if (mi.href) {
|
|
link.href = mi.href.replace(/\x7B0\x7D/gim, value); // for NavigateUrl actions;
|
|
if (mi.target) {
|
|
link.setAttribute("target", mi.target);
|
|
}
|
|
}
|
|
else if (mi.onclick) {
|
|
link.item = mi;
|
|
link.onclick = mi.onclick;
|
|
link.ontouchend = mi.onclick;
|
|
}
|
|
else if (mi.command) {
|
|
var assign = function(mi, link) {
|
|
return function(e) {
|
|
var source = link.source;
|
|
var item = mi;
|
|
item.action = item.action ? item.action : 'CallBack';
|
|
var cal = source.calendar || source.root;
|
|
|
|
if (source instanceof DayPilot.Link) {
|
|
cal.internal.linkMenuClick(item.command, source, item.action);
|
|
return;
|
|
}
|
|
else if (source instanceof DayPilot.Selection) {
|
|
cal.internal.timeRangeMenuClick(item.command, source, item.action);
|
|
return;
|
|
}
|
|
else if (source instanceof DayPilot.Event) {
|
|
cal.internal.eventMenuClick(item.command, source, item.action);
|
|
return;
|
|
}
|
|
else if (source instanceof DayPilot.Selection) {
|
|
cal.internal.timeRangeMenuClick(item.command, source, item.action);
|
|
return;
|
|
}
|
|
else if (source instanceof DayPilot.Task) {
|
|
if (source.menuType === "resource") {
|
|
cal.internal.resourceHeaderMenuClick(item.command, link.menuSource, item.action);
|
|
}
|
|
else {
|
|
cal.internal.eventMenuClick(item.command, link.menuSource, item.action);
|
|
}
|
|
return;
|
|
}
|
|
else {
|
|
switch (source.menuType) { // TODO legacy, remove
|
|
case 'resource':
|
|
cal.internal.resourceHeaderMenuClick(item.command, source, item.action);
|
|
return;
|
|
case 'selection': // fully replaced
|
|
cal.internal.timeRangeMenuClick(item.command, source, item.action);
|
|
return;
|
|
default: // fully replaced
|
|
cal.internal.eventMenuClick(item.command, source, item.action);
|
|
return;
|
|
}
|
|
}
|
|
|
|
e.preventDefault();
|
|
};
|
|
};
|
|
link.onclick = assign(mi, link);
|
|
link.ontouchend = assign(mi, link);
|
|
}
|
|
if (e && e.isRow && e.$.row.task) {
|
|
link.source = new DayPilot.Task(e.$.row.task, e.calendar);
|
|
link.source.menuType = "resource";
|
|
}
|
|
else if (e && e.isEvent && e.data.task) {
|
|
link.source = new DayPilot.Task(e, e.calendar);
|
|
}
|
|
else {
|
|
link.source = e;
|
|
}
|
|
link.menuSource = e;
|
|
|
|
var span = document.createElement("span");
|
|
span.innerHTML = mi.text;
|
|
link.appendChild(span);
|
|
|
|
if (mi.image) {
|
|
var image = document.createElement("img");
|
|
image.src = mi.image;
|
|
image.style.position = 'absolute';
|
|
image.style.top = '0px';
|
|
image.style.left = '0px';
|
|
|
|
link.appendChild(image);
|
|
}
|
|
|
|
var assignOnMouseOver = function(mi, link) {
|
|
return function() {
|
|
var source = link.source;
|
|
var item = mi;
|
|
|
|
// some delay
|
|
setTimeout(function() {
|
|
if (menu._state.submenu && menu._state.submenu.item === item) { // already visible
|
|
return;
|
|
}
|
|
|
|
if (menu._state.submenu && menu._state.submenu.item !== item) { // hide other
|
|
menu._state.submenu.menu.hide();
|
|
menu._state.submenu = null;
|
|
}
|
|
|
|
if (!item.items) { // no submenu for this item
|
|
return;
|
|
}
|
|
|
|
var options = menu.cloneOptions();
|
|
options.items = item.items;
|
|
|
|
menu._state.submenu = {};
|
|
menu._state.submenu.menu = new DayPilot.Menu(options);
|
|
menu._state.submenu.menu.show(source, true);
|
|
menu._state.submenu.item = item;
|
|
}, 500);
|
|
};
|
|
};
|
|
|
|
//if (mi.items) {
|
|
link.onmouseover = assignOnMouseOver(mi, link);
|
|
//}
|
|
|
|
item.appendChild(link);
|
|
}
|
|
|
|
div.appendChild(item);
|
|
|
|
}
|
|
|
|
var delayedDismiss = function(e) {
|
|
window.setTimeout(function() {
|
|
DayPilotMenu.menuClean();
|
|
}, 100);
|
|
};
|
|
|
|
div.onclick = delayedDismiss;
|
|
div.ontouchend = delayedDismiss;
|
|
|
|
div.onmousedown = function(e) {
|
|
e = e || window.event;
|
|
e.cancelBubble = true;
|
|
if (e.stopPropagation)
|
|
e.stopPropagation();
|
|
};
|
|
div.oncontextmenu = function() {
|
|
return false;
|
|
};
|
|
|
|
document.body.appendChild(div);
|
|
menu._state.visible = true;
|
|
menu._state.source = e;
|
|
|
|
div.style.display = '';
|
|
var height = div.clientHeight;
|
|
var width = div.offsetWidth;
|
|
div.style.display = 'none';
|
|
|
|
// don't show the menu outside of the visible window
|
|
var windowHeight = document.documentElement.clientHeight;
|
|
// windowHeight = document.body.clientHeight;
|
|
|
|
if (!this._state.ref) {
|
|
// don't show it exactly under the cursor
|
|
var x = DayPilotMenu.mouse.x + 1;
|
|
var y = DayPilotMenu.mouse.y + 1;
|
|
|
|
if (DayPilotMenu.mouse.clientY > windowHeight - height && windowHeight !== 0) {
|
|
var offsetY = DayPilotMenu.mouse.clientY - (windowHeight - height) + 5;
|
|
div.style.top = (y - offsetY) + 'px';
|
|
}
|
|
else {
|
|
div.style.top = y + 'px';
|
|
}
|
|
|
|
var windowWidth = document.documentElement.clientWidth;
|
|
|
|
if (DayPilotMenu.mouse.clientX > windowWidth - width && windowWidth !== 0) {
|
|
var offsetX = DayPilotMenu.mouse.clientX - (windowWidth - width) + 5;
|
|
div.style.left = (x - offsetX) + 'px';
|
|
}
|
|
else {
|
|
div.style.left = x + 'px';
|
|
}
|
|
}
|
|
else {
|
|
var pos = DayPilot.abs(this._state.ref);
|
|
var height = this._state.ref.offsetHeight;
|
|
|
|
div.style.left = pos.x + "px";
|
|
div.style.top = (pos.y + height) + "px";
|
|
|
|
}
|
|
div.style.display = '';
|
|
|
|
this.addShadow(div);
|
|
this._state.div = div;
|
|
|
|
if (!submenu) {
|
|
DayPilot.Menu.active = this;
|
|
}
|
|
};
|
|
|
|
this.applyCssClass = function(part) {
|
|
var prefix = this.theme || this.cssClassPrefix;
|
|
var sep = (this.cssOnly ? "_" : "");
|
|
if (prefix) {
|
|
return prefix + sep + part;
|
|
}
|
|
else {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
this.cloneOptions = function() {
|
|
var options = {};
|
|
var properties = ['cssOnly', 'cssClassPrefix', 'useShadow', 'zIndex'];
|
|
|
|
for(var i = 0; i < properties.length; i++) {
|
|
var p = properties[i];
|
|
options[p] = this[p];
|
|
}
|
|
|
|
return options;
|
|
};
|
|
|
|
this.hide = function() {
|
|
if (this._state.submenu) {
|
|
this._state.submenu.menu.hide();
|
|
}
|
|
|
|
this.removeShadow();
|
|
if (this._state.div && this._state.div.parentNode === document.body) {
|
|
document.body.removeChild(this._state.div);
|
|
}
|
|
|
|
menu._state.visible = false;
|
|
menu._state.source = null;
|
|
};
|
|
|
|
this.delayedHide = function() {
|
|
DayPilotMenu.hideTimeout = setTimeout(function() {
|
|
menu.hide();
|
|
}, 200);
|
|
};
|
|
|
|
this.cancelHideTimeout = function() {
|
|
clearTimeout(DayPilotMenu.hideTimeout);
|
|
};
|
|
|
|
// detects the mouse position, use when creating menu right before opening (.show)
|
|
this.init = function(ev) {
|
|
DayPilotMenu.mouseMove(ev);
|
|
};
|
|
|
|
this.addShadow = function(object) {
|
|
if (!this.useShadow || this.cssOnly) { // shadow is disabled
|
|
return;
|
|
}
|
|
if (!object) {
|
|
return;
|
|
}
|
|
if (this._state.shadows && this._state.shadows.length > 0) {
|
|
this.removeShadow();
|
|
}
|
|
this._state.shadows = [];
|
|
|
|
for (var i = 0; i < 5; i++) {
|
|
var shadow = document.createElement('div');
|
|
|
|
shadow.style.position = 'absolute';
|
|
shadow.style.width = object.offsetWidth + 'px';
|
|
shadow.style.height = object.offsetHeight + 'px';
|
|
|
|
shadow.style.top = object.offsetTop + i + 'px';
|
|
shadow.style.left = object.offsetLeft + i + 'px';
|
|
shadow.style.zIndex = this.zIndex;
|
|
|
|
shadow.style.filter = 'alpha(opacity:10)';
|
|
shadow.style.opacity = 0.1;
|
|
shadow.style.backgroundColor = '#000000';
|
|
|
|
document.body.appendChild(shadow);
|
|
this._state.shadows.push(shadow);
|
|
}
|
|
};
|
|
|
|
this.removeShadow = function() {
|
|
if (!this._state.shadows) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < this._state.shadows.length; i++) {
|
|
document.body.removeChild(this._state.shadows[i]);
|
|
}
|
|
this._state.shadows = [];
|
|
};
|
|
|
|
var options = DayPilot.isArray(items) ? null : items;
|
|
if (options) {
|
|
for (var name in options) {
|
|
this[name] = options[name];
|
|
}
|
|
}
|
|
|
|
if (!DayPilotMenu.clickRegistered) {
|
|
DayPilot.re(document, 'mousemove', DayPilotMenu.mouseMove);
|
|
DayPilot.re(document, 'touchmove', DayPilotMenu.touchMove);
|
|
DayPilot.re(document, 'touchstart', DayPilotMenu.touchStart);
|
|
DayPilot.re(document, 'touchend', DayPilotMenu.touchEnd);
|
|
DayPilot.re(document, 'mousedown', DayPilotMenu.menuClean);
|
|
DayPilotMenu.clickRegistered = true;
|
|
}
|
|
};
|
|
|
|
DayPilotMenu.menuClean = function(ev) {
|
|
if (typeof(DayPilot.Menu.active) === 'undefined')
|
|
return;
|
|
|
|
if (DayPilot.Menu.active) {
|
|
DayPilot.Menu.active.hide();
|
|
DayPilot.Menu.active = null;
|
|
}
|
|
|
|
};
|
|
|
|
DayPilotMenu.mouseMove = function(ev) {
|
|
if (typeof(DayPilotMenu) === 'undefined')
|
|
return;
|
|
DayPilotMenu.mouse = DayPilotMenu.mousePosition(ev);
|
|
};
|
|
|
|
DayPilotMenu.touchMove = function(ev) {
|
|
if (typeof(DayPilotMenu) === 'undefined') {
|
|
return;
|
|
}
|
|
DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev);
|
|
};
|
|
|
|
DayPilotMenu.touchStart = function(ev) {
|
|
if (typeof(DayPilotMenu) === 'undefined') {
|
|
return;
|
|
}
|
|
//DayPilotMenu.menuClean();
|
|
DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev);
|
|
};
|
|
|
|
DayPilotMenu.touchEnd = function(ev) {
|
|
//DayPilotMenu.menuClean();
|
|
};
|
|
|
|
DayPilotMenu.touchPosition = function(ev) {
|
|
var touch = ev.touches[0];
|
|
var mouse = {};
|
|
mouse.x = touch.pageX;
|
|
mouse.y = touch.pageY;
|
|
mouse.clientX = touch.clientX;
|
|
mouse.clientY = touch.clientY;
|
|
return mouse;
|
|
};
|
|
|
|
DayPilotMenu.mousePosition = function(e) {
|
|
var posx = 0;
|
|
var posy = 0;
|
|
if (!e)
|
|
var e = window.event;
|
|
if (e.pageX || e.pageY) {
|
|
posx = e.pageX;
|
|
posy = e.pageY;
|
|
}
|
|
else if (e.clientX || e.clientY) {
|
|
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
|
|
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
|
|
}
|
|
|
|
var result = {};
|
|
result.x = posx;
|
|
result.y = posy;
|
|
result.clientY = e.clientY;
|
|
result.clientX = e.clientX;
|
|
return result;
|
|
};
|
|
|
|
DayPilot.Menu.touchPosition = function(ev) {
|
|
DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev);
|
|
};
|
|
// publish the API
|
|
|
|
|
|
// (backwards compatibility)
|
|
//DayPilot.MonthVisible.dragStart = DayPilotMonth.dragStart;
|
|
DayPilot.MenuVisible.Menu = DayPilotMenu.Menu;
|
|
|
|
// current
|
|
//DayPilot.Menu = DayPilotMenu.Menu;
|
|
|
|
if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) {
|
|
Sys.Application.notifyScriptLoaded();
|
|
}
|
|
|
|
|
|
})();
|