diff --git a/bower.json b/bower.json index a534db2..91f32e5 100644 --- a/bower.json +++ b/bower.json @@ -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", diff --git a/dist/ng-context-menu.js b/dist/ng-context-menu.js index d0ea9b1..71809d3 100644 --- a/dist/ng-context-menu.js +++ b/dist/ng-context-menu.js @@ -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); \ No newline at end of file diff --git a/dist/ng-context-menu.min.js b/dist/ng-context-menu.min.js index c3ddf53..8a08314 100644 --- a/dist/ng-context-menu.min.js +++ b/dist/ng-context-menu.min.js @@ -1 +1 @@ -angular.module("ng-context-menu",[]).factory("ContextMenuService",function(){return{element:null,menuElement:null}}).directive("contextMenu",["$document","ContextMenuService",function(e,n){return{restrict:"A",scope:{callback:"&contextMenu",disabled:"&contextMenuDisabled",closeCallback:"&contextMenuClose"},link:function(t,l,c){function o(n,t){t.addClass("open");var l=e[0].documentElement,c=(window.pageXOffset||l.scrollLeft)-(l.clientLeft||0),o=(window.pageYOffset||l.scrollTop)-(l.clientTop||0),u=t[0].scrollWidth,i=t[0].scrollHeight,a=l.clientWidth+c,d=l.clientHeight+o,p=u+n.pageX,s=i+n.pageY,r=Math.max(n.pageX-c,0),f=Math.max(n.pageY-o,0);p>a&&(r-=p-a),s>d&&(f-=s-d),t.css("top",f+"px"),t.css("left",r+"px"),m=!0}function u(e){e.removeClass("open"),m&&t.closeCallback(),m=!1}function i(e){!t.disabled()&&m&&27===e.keyCode&&t.$apply(function(){u(n.menuElement)})}function a(e){t.disabled()||!m||2===e.button&&e.target===n.element||t.$apply(function(){u(n.menuElement)})}var m=!1;l.bind("contextmenu",function(e){t.disabled()||(null!==n.menuElement&&u(n.menuElement),n.menuElement=angular.element(document.getElementById(c.target)),n.element=e.target,e.preventDefault(),e.stopPropagation(),t.$apply(function(){t.callback({$event:e})}),t.$apply(function(){o(e,n.menuElement)}))}),e.bind("keyup",i),e.bind("click",a),e.bind("contextmenu",a),t.$on("$destroy",function(){e.unbind("keyup",i),e.unbind("click",a),e.unbind("contextmenu",a)})}}}]); \ No newline at end of file +!function(e){"use strict";e.module("ng-context-menu",[]).factory("ContextMenuService",function(){return{element:null,menuElement:null}}).directive("contextMenu",["$document","ContextMenuService",function(n,t){return{restrict:"A",scope:{callback:"&contextMenu",disabled:"&contextMenuDisabled",closeCallback:"&contextMenuClose",marginBottom:"@contextMenuMarginBottom"},link:function(l,o,c){function i(e,t){t.addClass("open");var o,c,i=n[0].documentElement,u=(window.pageXOffset||i.scrollLeft)-(i.clientLeft||0),a=(window.pageYOffset||i.scrollTop)-(i.clientTop||0),m=t[0].scrollWidth,s=t[0].scrollHeight;if(e.pageX||e.pageY)o=e.pageX,c=e.pageY;else{var d=n[0].body;o=e.clientX+d.scrollLeft+i.scrollLeft,c=e.clientY+d.scrollTop+i.scrollTop}var p=i.clientWidth+u,f=i.clientHeight+a,b=m+o,g=s+c,x=Math.max(o-u,0),v=Math.max(c-a,0);if(b>p&&(x-=b-p),g>f){var y=l.marginBottom||0;v=v-(g-f)-y}t.css("top",v+"px"),t.css("left",x+"px"),r=!0}function u(e){e.removeClass("open"),r&&l.closeCallback(),r=!1}function a(e){!l.disabled()&&r&&27===e.keyCode&&l.$apply(function(){u(t.menuElement)})}function m(e){l.disabled()||!r||2===e.button&&e.target===t.element||l.$apply(function(){u(t.menuElement)})}var r=!1;o.bind("contextmenu",function(n){l.disabled()||(null!==t.menuElement&&u(t.menuElement),t.menuElement=e.element(document.getElementById(c.target)),t.element=n.target,n.preventDefault(),n.stopPropagation(),l.$apply(function(){l.callback({$event:n})}),l.$apply(function(){i(n,t.menuElement)}))}),n.bind("keyup",a),n.bind("click",m),n.bind("contextmenu",m),l.$on("$destroy",function(){n.unbind("keyup",a),n.unbind("click",m),n.unbind("contextmenu",m)})}}}])}(angular); \ No newline at end of file diff --git a/package.json b/package.json index f82d902..f504f7a 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/ng-context-menu.js b/src/ng-context-menu.js index ac37856..71809d3 100644 --- a/src/ng-context-menu.js +++ b/src/ng-context-menu.js @@ -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) @@ -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); @@ -80,7 +94,6 @@ document.getElementById($attrs.target) ); ContextMenuService.element = event.target; - //console.log('set', ContextMenuService.element); event.preventDefault(); event.stopPropagation(); @@ -94,7 +107,6 @@ }); function handleKeyUpEvent(event) { - //console.log('keyup'); if (!$scope.disabled() && opened && event.keyCode === 27) { $scope.$apply(function() { close(ContextMenuService.menuElement); @@ -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);