overleaf/services/web/public/js/libs/ng-context-menu-0.1.4.js

108 lines
3.7 KiB
JavaScript

/**
* ng-context-menu - v0.1.4 - An AngularJS directive to display a context menu when a right-click event is triggered
*
* @author Ian Kennington Walter (http://ianvonwalter.com)
*/
angular
.module('ng-context-menu', [])
.factory('ContextMenuService', function() {
return {
element: null,
menuElement: null,
container: null
};
})
.directive('contextMenu', ['$document', 'ContextMenuService', function($document, ContextMenuService) {
return {
restrict: 'A',
scope: {
'callback': '&contextMenu',
'disabled': '&contextMenuDisabled'
},
link: function($scope, $element, $attrs) {
var opened = false;
function open(event, menuElement, container) {
menuElement.addClass('open');
if (container) {
container.append(menuElement);
}
var doc = $document[0].documentElement;
var docLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),
docTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0),
elementHeight = menuElement[0].scrollHeight;
var docHeight = doc.clientHeight + docTop,
totalHeight = elementHeight + event.pageY,
top = Math.max(event.pageY - docTop, 0);
if (totalHeight > docHeight) {
top = top - (totalHeight - docHeight);
}
menuElement.css('top', top + 'px');
menuElement.css('left', Math.max(event.pageX - docLeft, 0) + 'px');
opened = true;
}
function close(menuElement) {
menuElement.removeClass('open');
opened = false;
}
$element.bind('contextmenu', function(event) {
if (!$scope.disabled()) {
if (ContextMenuService.menuElement !== null) {
close(ContextMenuService.menuElement);
}
ContextMenuService.menuElement = angular.element(document.getElementById($attrs.target));
if (typeof($attrs.contextMenuContainer) != "undefined") {
ContextMenuService.container = angular.element($attrs.contextMenuContainer)
}
ContextMenuService.element = event.target;
// console.log('set', ContextMenuService.element);
event.preventDefault();
event.stopPropagation();
$scope.$apply(function() {
$scope.callback({ $event: event });
open(event, ContextMenuService.menuElement, ContextMenuService.container);
});
}
});
function handleKeyUpEvent(event) {
//console.log('keyup');
if (!$scope.disabled() && opened && event.keyCode === 27) {
$scope.$apply(function() {
close(ContextMenuService.menuElement);
});
}
}
function handleClickEvent(event) {
if (!$scope.disabled() &&
opened &&
(event.button !== 2 || event.target !== ContextMenuService.element)) {
$scope.$apply(function() {
close(ContextMenuService.menuElement);
});
}
}
$document.bind('keyup', handleKeyUpEvent);
// Firefox treats a right-click as a click and a contextmenu event while other browsers
// just treat it as a contextmenu event
$document.bind('click', handleClickEvent);
$document.bind('contextmenu', handleClickEvent);
$scope.$on('$destroy', function() {
//console.log('destroy');
$document.unbind('keyup', handleKeyUpEvent);
$document.unbind('click', handleClickEvent);
$document.unbind('contextmenu', handleClickEvent);
});
}
};
}]);