diff --git a/src/components/dragelement/index.js b/src/components/dragelement/index.js index b2396952d18..e188216911f 100644 --- a/src/components/dragelement/index.js +++ b/src/components/dragelement/index.js @@ -77,6 +77,30 @@ dragElement.init = function init(options) { element.onmousedown = onStart; element.ontouchstart = onStart; + function onContextMenu(e) { + if(gd._context.rightClick) { + return; + } + var e2; + e.preventDefault(); + try { + e2 = new MouseEvent('contextmenu', e); + } + catch(err) { + var offset = pointerOffset(e); + e2 = document.createEvent('MouseEvents'); + e2.initMouseEvent('contextmenu', + e.bubbles, e.cancelable, + e.view, e.detail, + e.screenX, e.screenY, + offset[0], offset[1], + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + e.button, initialTarget); + } + initialTarget.dispatchEvent(e2); + onDone(e); + } + function onStart(e) { // make dragging and dragged into properties of gd // so that others can look at and modify them @@ -111,6 +135,7 @@ dragElement.init = function init(options) { document.documentElement.style.cursor = window.getComputedStyle(element).cursor; } + document.addEventListener('contextmenu', onContextMenu); document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onDone); document.addEventListener('touchmove', onMove); @@ -138,6 +163,7 @@ dragElement.init = function init(options) { } function onDone(e) { + document.removeEventListener('contextmenu', onContextMenu); document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onDone); document.removeEventListener('touchmove', onMove); diff --git a/src/plot_api/plot_config.js b/src/plot_api/plot_config.js index 27f4735a24e..9f690c775de 100644 --- a/src/plot_api/plot_config.js +++ b/src/plot_api/plot_config.js @@ -62,6 +62,9 @@ module.exports = { // double click interaction (false, 'reset', 'autosize' or 'reset+autosize') doubleClick: 'reset+autosize', + // right click interaction, if false browser context menu won't be shown, syntetic contextmenu event instead + rightClick: true, + // new users see some hints about interactivity showTips: true, diff --git a/test/jasmine/tests/dragelement_test.js b/test/jasmine/tests/dragelement_test.js index a0151c95d78..a7016d4c912 100644 --- a/test/jasmine/tests/dragelement_test.js +++ b/test/jasmine/tests/dragelement_test.js @@ -148,6 +148,24 @@ describe('dragElement', function() { expect(mockObj.dummy).not.toHaveBeenCalled(); }); + + it('should fire contextmenu event on element when option rightclick set to false', function() { + var options = { element: this.element, gd: this.gd }; + options.gd._context = { rightClick: false }; + dragElement.init(options); + + var mockObj = { + handleContextMenu: function() {} + }; + spyOn(mockObj, 'handleContextMenu'); + + this.element.oncontextmenu = mockObj.handleContextMenu; + + mouseEvent('mousedown', this.x, this.y); + mouseEvent('contextmenu', this.x, this.y); + + expect(mockObj.handleContextMenu).toHaveBeenCalled(); + }); }); describe('dragElement.getCursor', function() {