├── .bower.json ├── .gitignore ├── .npmignore ├── CHANGES.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bower.json ├── dist ├── ng-context-menu.js └── ng-context-menu.min.js ├── package.json └── protractor.conf.js /.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-context-menu", 3 | "version": "1.0.1", 4 | "description": "An AngularJS directive to display a context menu when a right-click event is triggered", 5 | "keywords": [ 6 | "ng-context-menu", 7 | "context menu", 8 | "right click", 9 | "angularjs", 10 | "angular" 11 | ], 12 | "authors": [ 13 | "Ian Kennington Walter (http://ianvonwalter.com)" 14 | ], 15 | "license": "MIT", 16 | "homepage": "http://ianwalter.github.io/ng-context-menu/", 17 | "main": [ 18 | "dist/ng-context-menu.js" 19 | ], 20 | "ignore": [ 21 | "**/.*", 22 | "node_modules", 23 | "test", 24 | "public", 25 | "src", 26 | "index.html", 27 | "gulpfile.js", 28 | "package.json" 29 | ], 30 | "dependencies": { 31 | "angular": ">= 1.2.5" 32 | }, 33 | "devDependencies": { 34 | "requirejs": "~2.1.15" 35 | }, 36 | "_release": "1.0.1", 37 | "_resolution": { 38 | "type": "version", 39 | "tag": "v1.0.1", 40 | "commit": "50257bab3efc9abbb1bd433167002e36dd0b591c" 41 | }, 42 | "_source": "git://github.com/ianwalter/ng-context-menu.git", 43 | "_target": "1.0.1", 44 | "_originalSource": "ng-context-menu" 45 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/.* 2 | node_modules 3 | test 4 | public 5 | src 6 | index.html 7 | gulpfile.js 8 | package.json 9 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # Changes to ng-context-menu 2 | 3 | ## v0.1.7 4 | 5 | 1. Added #26: Separately apply callback before opening menu. Thanks @hupfis! 6 | 2. Added #7: Add "Step 4: Add your menu markup" to README instructions. 7 | 3. Added #25: Allow context menu to be closed even in disabled mode. Thanks @NOtherDev! 8 | 9 | ## v0.1.6 10 | 11 | 1. Fixed #18: Changed main file in bower.json configuration from ng-context-menu.min.js to ng-context-menu.js. Thanks @Hypercubed! 12 | 2. Fixed #20: Prevented the context menu from displaying on the right side outside of the visible browser window. Thanks @alexk111! 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ng-context-menu 2 | 3 | 1. Follow [Airbnb's JavaScript Style Guide](https://github.com/airbnb/javascript) 4 | 2. Run ```bower install``` in the root directory 5 | 3. Run ```gulp``` to execute development tasks such as linting the source, creating the distribution 6 | files and running a development server. You'll need to run ```npm install``` in order to install the development 7 | dependencies and ```npm install -g gulp``` in order to install [gulp](http://gulpjs.com). The development server should 8 | be available at [http://localhost:8080/](http://localhost:8080/). 9 | 3. Increment the version number in package.json, bower.json, and src/ng-context-menu.js 10 | 5. Create pull requests on the **development** branch not master! 11 | 12 | Thank you for your contribution! 13 | 14 | «–– [Ian](http://ianvonwalter.com) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Ian Walter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Originally ianwalter/ng-context-menu 2 | 3 | This project is not maintained any longer. Please feel free to fork it if you need to make changes to the library. 4 | 5 | # [ng-context-menu](http://ianwalter.github.io/ng-context-menu/) 6 | *An AngularJS directive to display a context menu when a right-click event is triggered* 7 | 8 | #### Step 1: Install ng-context-menu 9 | 10 | Install using Bower: 11 | 12 | ``` 13 | bower install ng-context-menu --save 14 | ``` 15 | 16 | Include ng-context-menu.min.js in your app. 17 | 18 | #### Step 2: Load the ng-context-menu module 19 | 20 | ```javascript 21 | var app = angular.module('menu-demo', ['ngRoute', 'ng-context-menu']) 22 | ``` 23 | 24 | #### Step 3: Add the context-menu directive to a DOM element 25 | 26 | ```html 27 |
30 | ... 31 |
32 | ``` 33 | #### Step 4: Add the markup of the menu you want to be displayed 34 | 35 | Customize the menu to your needs. It may look something like: 36 | 37 | ```html 38 | 79 | ``` 80 | 81 | #### Step 5: Make sure your menu is has the ```position: fixed``` CSS property 82 | 83 | As you can see in the demo, I just created a class called position-fixed and added the property: 84 | 85 | ```css 86 | .position-fixed { 87 | position: fixed; 88 | } 89 | ``` 90 | 91 | #### Disabling the contextmenu 92 | 93 | If you need to disable the contextmenu in certain circumstances, you can add an expression to the 94 | ```context-menu-disabled``` attribute. If the expression evaluates to true, the contextmenu will be 95 | disabled, for example, ```context-menu-disabled="1 === 1"``` 96 | 97 | That's it, I hope you find this useful! 98 | 99 | #### `close` Callback 100 | 101 | Add the following attribute to the `context-menu` element: `context-menu-close` which should be a function 102 | that will be called whenever the context menu is closed. 103 | 104 | ```html 105 |
106 | ``` 107 | 108 | «–– [Ian](http://ianvonwalter.com) 109 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-context-menu", 3 | "version": "1.0.1", 4 | "description": "An AngularJS directive to display a context menu when a right-click event is triggered", 5 | "keywords": [ 6 | "ng-context-menu", 7 | "context menu", 8 | "right click", 9 | "angularjs", 10 | "angular" 11 | ], 12 | "authors": [ 13 | "Ian Kennington Walter (http://ianvonwalter.com)" 14 | ], 15 | "license": "MIT", 16 | "homepage": "http://ianwalter.github.io/ng-context-menu/", 17 | "main": [ 18 | "dist/ng-context-menu.js" 19 | ], 20 | "ignore": [ 21 | "**/.*", 22 | "node_modules", 23 | "test", 24 | "public", 25 | "src", 26 | "index.html", 27 | "gulpfile.js", 28 | "package.json" 29 | ], 30 | "dependencies": { 31 | "angular": ">= 1.2.5" 32 | }, 33 | "devDependencies": { 34 | "requirejs": "~2.1.15" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dist/ng-context-menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ng-context-menu - v1.0.1 - An AngularJS directive to display a context menu 3 | * when a right-click event is triggered 4 | * 5 | * @author Ian Kennington Walter (http://ianvonwalter.com) 6 | */ 7 | angular 8 | .module('ng-context-menu', []) 9 | .factory('ContextMenuService', function() { 10 | return { 11 | element: null, 12 | menuElement: null 13 | }; 14 | }) 15 | .directive('contextMenu', [ 16 | '$document', 17 | 'ContextMenuService', 18 | function($document, ContextMenuService) { 19 | return { 20 | restrict: 'A', 21 | scope: { 22 | 'callback': '&contextMenu', 23 | 'disabled': '&contextMenuDisabled', 24 | 'closeCallback': '&contextMenuClose' 25 | }, 26 | link: function($scope, $element, $attrs) { 27 | var opened = false; 28 | 29 | function open(event, menuElement) { 30 | menuElement.addClass('open'); 31 | 32 | var doc = $document[0].documentElement; 33 | var docLeft = (window.pageXOffset || doc.scrollLeft) - 34 | (doc.clientLeft || 0), 35 | docTop = (window.pageYOffset || doc.scrollTop) - 36 | (doc.clientTop || 0), 37 | elementWidth = menuElement[0].scrollWidth, 38 | elementHeight = menuElement[0].scrollHeight; 39 | var docWidth = doc.clientWidth + docLeft, 40 | docHeight = doc.clientHeight + docTop, 41 | totalWidth = elementWidth + event.pageX, 42 | totalHeight = elementHeight + event.pageY, 43 | left = Math.max(event.pageX - docLeft, 0), 44 | top = Math.max(event.pageY - docTop, 0); 45 | 46 | if (totalWidth > docWidth) { 47 | left = left - (totalWidth - docWidth); 48 | } 49 | 50 | if (totalHeight > docHeight) { 51 | top = top - (totalHeight - docHeight); 52 | } 53 | 54 | menuElement.css('top', top + 'px'); 55 | menuElement.css('left', left + 'px'); 56 | opened = true; 57 | } 58 | 59 | function close(menuElement) { 60 | menuElement.removeClass('open'); 61 | 62 | if (opened) { 63 | $scope.closeCallback(); 64 | } 65 | 66 | opened = false; 67 | } 68 | 69 | $element.bind('contextmenu', function(event) { 70 | if (!$scope.disabled()) { 71 | if (ContextMenuService.menuElement !== null) { 72 | close(ContextMenuService.menuElement); 73 | } 74 | ContextMenuService.menuElement = angular.element( 75 | document.getElementById($attrs.target) 76 | ); 77 | ContextMenuService.element = event.target; 78 | //console.log('set', ContextMenuService.element); 79 | 80 | event.preventDefault(); 81 | event.stopPropagation(); 82 | $scope.$apply(function() { 83 | $scope.callback({ $event: event }); 84 | }); 85 | $scope.$apply(function() { 86 | open(event, ContextMenuService.menuElement); 87 | }); 88 | } 89 | }); 90 | 91 | function handleKeyUpEvent(event) { 92 | //console.log('keyup'); 93 | if (!$scope.disabled() && opened && event.keyCode === 27) { 94 | $scope.$apply(function() { 95 | close(ContextMenuService.menuElement); 96 | }); 97 | } 98 | } 99 | 100 | function handleClickEvent(event) { 101 | if (!$scope.disabled() && 102 | opened && 103 | (event.button !== 2 || 104 | event.target !== ContextMenuService.element)) { 105 | $scope.$apply(function() { 106 | close(ContextMenuService.menuElement); 107 | }); 108 | } 109 | } 110 | 111 | $document.bind('keyup', handleKeyUpEvent); 112 | // Firefox treats a right-click as a click and a contextmenu event 113 | // while other browsers just treat it as a contextmenu event 114 | $document.bind('click', handleClickEvent); 115 | $document.bind('contextmenu', handleClickEvent); 116 | 117 | $scope.$on('$destroy', function() { 118 | //console.log('destroy'); 119 | $document.unbind('keyup', handleKeyUpEvent); 120 | $document.unbind('click', handleClickEvent); 121 | $document.unbind('contextmenu', handleClickEvent); 122 | }); 123 | } 124 | }; 125 | } 126 | ]); 127 | -------------------------------------------------------------------------------- /dist/ng-context-menu.min.js: -------------------------------------------------------------------------------- 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)})}}}]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "ng-context-menu", 4 | "version": "1.0.1", 5 | "description": "An AngularJS directive to display a context menu when a right-click event is triggered", 6 | "keywords": [ 7 | "ng-context-menu", 8 | "context menu", 9 | "right click", 10 | "angularjs", 11 | "angular" 12 | ], 13 | "authors": [ 14 | "Ian Kennington Walter (http://ianvonwalter.com)" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/Swimlane/ng-context-menu" 19 | }, 20 | "license": "MIT", 21 | "homepage": "http://ianwalter.github.io/ng-context-menu/", 22 | "main": "dist/ng-context-menu.js", 23 | "dependencies": { 24 | "angular": ">= 1.2.5" 25 | }, 26 | "devDependencies": { 27 | "requirejs": "~2.1.15" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | var GulpSelenium = require('gulp-selenium'); 2 | var gulpSelenium = GulpSelenium(); 3 | 4 | exports.config = { 5 | seleniumServerJar: gulpSelenium.path, 6 | chromeDriver: gulpSelenium.chromeDriverPath, 7 | //seleniumAddress: 'http://localhost:4444/wd/hub', // Using JAR instead of address 8 | capabilities: { 9 | 'browserName': 'phantomjs' 10 | }, 11 | specs: ['test/ui/**/*.spec.js'] 12 | }; --------------------------------------------------------------------------------