Skip to content

Commit

Permalink
fix positioning issue with IE
Browse files Browse the repository at this point in the history
  • Loading branch information
ajwild committed Mar 22, 2016
1 parent d2f60fa commit 481c00d
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 110 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ng-context-menu",
"version": "1.0.2",
"version": "1.0.3",
"description": "An AngularJS directive to display a context menu when a right-click event is triggered",
"keywords": [
"ng-context-menu",
Expand Down
215 changes: 116 additions & 99 deletions dist/ng-context-menu.js
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);
2 changes: 1 addition & 1 deletion dist/ng-context-menu.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ng-context-menu",
"version": "1.0.2",
"version": "1.0.3",
"description": "An AngularJS directive to display a context menu when a right-click event is triggered",
"main": "index.html",
"devDependencies": {
Expand Down
27 changes: 19 additions & 8 deletions src/ng-context-menu.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* ng-context-menu - v1.0.2 - 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)
Expand Down Expand Up @@ -40,12 +40,26 @@
(doc.clientTop || 0),
elementWidth = menuElement[0].scrollWidth,
elementHeight = menuElement[0].scrollHeight;
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 + event.pageX,
totalHeight = elementHeight + event.pageY,
left = Math.max(event.pageX - docLeft, 0),
top = Math.max(event.pageY - docTop, 0);
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);
Expand Down Expand Up @@ -80,7 +94,6 @@
document.getElementById($attrs.target)
);
ContextMenuService.element = event.target;
//console.log('set', ContextMenuService.element);

event.preventDefault();
event.stopPropagation();
Expand All @@ -94,7 +107,6 @@
});

function handleKeyUpEvent(event) {
//console.log('keyup');
if (!$scope.disabled() && opened && event.keyCode === 27) {
$scope.$apply(function() {
close(ContextMenuService.menuElement);
Expand All @@ -120,7 +132,6 @@
$document.bind('contextmenu', handleClickEvent);

$scope.$on('$destroy', function() {
//console.log('destroy');
$document.unbind('keyup', handleKeyUpEvent);
$document.unbind('click', handleClickEvent);
$document.unbind('contextmenu', handleClickEvent);
Expand Down

0 comments on commit 481c00d

Please sign in to comment.