forked from slively/ng-context-menu
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
138 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,143 @@ | ||
/** | ||
* ng-context-menu - v1.0.1 - An AngularJS directive to display a context menu | ||
* ng-context-menu - v1.0.3 - 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 | ||
}; | ||
}) | ||
.directive('contextMenu', [ | ||
'$document', | ||
'ContextMenuService', | ||
function($document, ContextMenuService) { | ||
(function(angular) { | ||
'use strict'; | ||
|
||
angular | ||
.module('ng-context-menu', []) | ||
.factory('ContextMenuService', function() { | ||
return { | ||
restrict: 'A', | ||
scope: { | ||
'callback': '&contextMenu', | ||
'disabled': '&contextMenuDisabled', | ||
'closeCallback': '&contextMenuClose' | ||
}, | ||
link: function($scope, $element, $attrs) { | ||
var opened = false; | ||
element: null, | ||
menuElement: null | ||
}; | ||
}) | ||
.directive('contextMenu', [ | ||
'$document', | ||
'ContextMenuService', | ||
function($document, ContextMenuService) { | ||
return { | ||
restrict: 'A', | ||
scope: { | ||
'callback': '&contextMenu', | ||
'disabled': '&contextMenuDisabled', | ||
'closeCallback': '&contextMenuClose', | ||
'marginBottom': '@contextMenuMarginBottom' | ||
}, | ||
link: function($scope, $element, $attrs) { | ||
var opened = false; | ||
|
||
function open(event, menuElement) { | ||
menuElement.addClass('open'); | ||
function open(event, menuElement) { | ||
menuElement.addClass('open'); | ||
|
||
var doc = $document[0].documentElement; | ||
var docLeft = (window.pageXOffset || doc.scrollLeft) - | ||
(doc.clientLeft || 0), | ||
var doc = $document[0].documentElement; | ||
var docLeft = (window.pageXOffset || doc.scrollLeft) - | ||
(doc.clientLeft || 0), | ||
docTop = (window.pageYOffset || doc.scrollTop) - | ||
(doc.clientTop || 0), | ||
(doc.clientTop || 0), | ||
elementWidth = menuElement[0].scrollWidth, | ||
elementHeight = menuElement[0].scrollHeight; | ||
var docWidth = doc.clientWidth + docLeft, | ||
docHeight = doc.clientHeight + docTop, | ||
totalWidth = elementWidth + event.pageX, | ||
totalHeight = elementHeight + event.pageY, | ||
left = Math.max(event.pageX - docLeft, 0), | ||
top = Math.max(event.pageY - docTop, 0); | ||
var pageX; | ||
var pageY; | ||
// browser compatibility fix for the click location | ||
if (event.pageX || event.pageY) { | ||
// use pageX and pageY when available (modern browsers) | ||
pageX = event.pageX; | ||
pageY = event.pageY; | ||
} else { | ||
// calculate pageX and pageY when they do not exist | ||
// (IE8 and generated events in later versions of IE) | ||
var docBody = $document[0].body; | ||
pageX = event.clientX + docBody.scrollLeft + doc.scrollLeft; | ||
pageY = event.clientY + docBody.scrollTop + doc.scrollTop; | ||
} | ||
var docWidth = doc.clientWidth + docLeft, | ||
docHeight = doc.clientHeight + docTop, | ||
totalWidth = elementWidth + pageX, | ||
totalHeight = elementHeight + pageY, | ||
left = Math.max(pageX - docLeft, 0), | ||
top = Math.max(pageY - docTop, 0); | ||
|
||
if (totalWidth > docWidth) { | ||
left = left - (totalWidth - docWidth); | ||
} | ||
if (totalWidth > docWidth) { | ||
left = left - (totalWidth - docWidth); | ||
} | ||
|
||
if (totalHeight > docHeight) { | ||
top = top - (totalHeight - docHeight); | ||
if (totalHeight > docHeight) { | ||
var marginBottom = $scope.marginBottom || 0; | ||
top = top - (totalHeight - docHeight) - marginBottom; | ||
} | ||
|
||
menuElement.css('top', top + 'px'); | ||
menuElement.css('left', left + 'px'); | ||
opened = true; | ||
} | ||
|
||
menuElement.css('top', top + 'px'); | ||
menuElement.css('left', left + 'px'); | ||
opened = true; | ||
} | ||
function close(menuElement) { | ||
menuElement.removeClass('open'); | ||
|
||
function close(menuElement) { | ||
menuElement.removeClass('open'); | ||
if (opened) { | ||
$scope.closeCallback(); | ||
} | ||
|
||
if (opened) { | ||
$scope.closeCallback(); | ||
opened = false; | ||
} | ||
|
||
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) | ||
); | ||
ContextMenuService.element = event.target; | ||
|
||
$element.bind('contextmenu', function(event) { | ||
if (!$scope.disabled()) { | ||
if (ContextMenuService.menuElement !== null) { | ||
close(ContextMenuService.menuElement); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
$scope.$apply(function() { | ||
$scope.callback({ $event: event }); | ||
}); | ||
$scope.$apply(function() { | ||
open(event, ContextMenuService.menuElement); | ||
}); | ||
} | ||
ContextMenuService.menuElement = angular.element( | ||
document.getElementById($attrs.target) | ||
); | ||
ContextMenuService.element = event.target; | ||
//console.log('set', ContextMenuService.element); | ||
|
||
event.preventDefault(); | ||
event.stopPropagation(); | ||
$scope.$apply(function() { | ||
$scope.callback({ $event: event }); | ||
}); | ||
$scope.$apply(function() { | ||
open(event, ContextMenuService.menuElement); | ||
}); | ||
} | ||
}); | ||
}); | ||
|
||
function handleKeyUpEvent(event) { | ||
//console.log('keyup'); | ||
if (!$scope.disabled() && opened && event.keyCode === 27) { | ||
$scope.$apply(function() { | ||
close(ContextMenuService.menuElement); | ||
}); | ||
function handleKeyUpEvent(event) { | ||
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); | ||
}); | ||
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); | ||
$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); | ||
}); | ||
} | ||
}; | ||
} | ||
]); | ||
$scope.$on('$destroy', function() { | ||
$document.unbind('keyup', handleKeyUpEvent); | ||
$document.unbind('click', handleClickEvent); | ||
$document.unbind('contextmenu', handleClickEvent); | ||
}); | ||
} | ||
}; | ||
} | ||
]); | ||
})(angular); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters