Merge pull request #342 from sourcelair/issue-#310-cross-browser-right-click

Make right-click work on all browsers
This commit is contained in:
Paris Kasidiaris
2016-11-04 20:40:53 +00:00
committed by GitHub
5 changed files with 83 additions and 49 deletions
+15 -11
View File
@@ -86,7 +86,7 @@ function pasteHandler(ev, term) {
*/
function rightClickHandler(ev, term) {
var s = document.getSelection(),
sText = prepareTextForClipboard(s.toString()),
selectedText = prepareTextForClipboard(s.toString()),
clickIsOnSelection = false;
if (s.rangeCount) {
@@ -102,23 +102,27 @@ function rightClickHandler(ev, term) {
(x > rect.left) && (x < rect.right) &&
(y > rect.top) && (y < rect.bottom)
);
// If we clicked on selection and selection is not a single space,
// then mark the right click as copy-only. We check for the single
// space selection, as this can happen when clicking on an &nbsp;
// and there is not much pointing in copying a single space.
if (clickIsOnSelection && (sText !== ' ')) {
if (clickIsOnSelection) {
break;
}
}
// If we clicked on selection and selection is not a single space,
// then mark the right click as copy-only. We check for the single
// space selection, as this can happen when clicking on an &nbsp;
// and there is not much pointing in copying a single space.
if (selectedText.match(/^\s$/) || !selectedText.length) {
clickIsOnSelection = false;
}
}
// Bring textarea at the cursor position
if (!clickIsOnSelection) {
term.textarea.style.position = 'fixed';
term.textarea.style.width = '10px';
term.textarea.style.height = '10px';
term.textarea.style.left = x + 'px';
term.textarea.style.top = y + 'px';
term.textarea.style.width = '20px';
term.textarea.style.height = '20px';
term.textarea.style.left = (x - 10) + 'px';
term.textarea.style.top = (y - 10) + 'px';
term.textarea.style.zIndex = 1000;
term.textarea.focus();
@@ -130,7 +134,7 @@ function rightClickHandler(ev, term) {
term.textarea.style.left = null;
term.textarea.style.top = null;
term.textarea.style.zIndex = null;
}, 1);
}, 4);
}
}
+27
View File
@@ -0,0 +1,27 @@
/**
* xterm.js: xterm, in the browser
* Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)
*/
/**
* Browser utilities module. This module contains attributes and methods to help with
* identifying the current browser and platform.
* @module xterm/utils/Browser
*/
import { contains } from './Generic.js';
let isNode = (typeof navigator == 'undefined') ? true : false;
let userAgent = (isNode) ? 'node' : navigator.userAgent;
let platform = (isNode) ? 'node' : navigator.platform;
export let isFirefox = !!~userAgent.indexOf('Firefox');
export let isMSIE = !!~userAgent.indexOf('MSIE');
// Find the users platform. We use this to interpret the meta key
// and ISO third level shifts.
// http://stackoverflow.com/q/19877924/577598
export let isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);
export let isIpad = platform === 'iPad';
export let isIphone = platform === 'iPhone';
export let isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);
+19
View File
@@ -0,0 +1,19 @@
/**
* xterm.js: xterm, in the browser
* Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)
*/
/**
* Generic utilities module. This module contains generic methods that can be helpful at
* different parts of the code base.
* @module xterm/utils/Generic
*/
/**
* Return if the given array contains the given element
* @param {Array} array The array to search for the given element.
* @param {Object} el The element to look for into the array
*/
export let contains = function(arr, el) {
return arr.indexOf(el) >= 0;
};
+20 -36
View File
@@ -35,6 +35,7 @@ import { CompositionHelper } from './CompositionHelper.js';
import { EventEmitter } from './EventEmitter.js';
import { Viewport } from './Viewport.js';
import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js';
import * as Browser from './utils/Browser';
/**
* Terminal Emulation References:
@@ -78,6 +79,7 @@ function Terminal(options) {
return new Terminal(arguments[0], arguments[1], arguments[2]);
}
self.browser = Browser;
self.cancel = Terminal.cancel;
EventEmitter.call(this);
@@ -449,9 +451,21 @@ Terminal.prototype.initGlobal = function() {
on(this.textarea, 'paste', function (ev) {
pasteHandler.call(this, ev, term);
});
on(this.element, 'contextmenu', function (ev) {
function rightClickHandlerWrapper (ev) {
rightClickHandler.call(this, ev, term);
});
}
if (term.browser.isFirefox || term.browser.isMSIE) {
on(this.element, 'mousedown', function (ev) {
if (ev.button == 2) {
rightClickHandlerWrapper(ev);
}
});
} else {
on(this.element, 'contextmenu', rightClickHandlerWrapper);
}
};
/**
@@ -526,27 +540,6 @@ Terminal.prototype.open = function(parent) {
this.document = this.parent.ownerDocument;
this.body = this.document.getElementsByTagName('body')[0];
// Parse User-Agent
if (this.context.navigator && this.context.navigator.userAgent) {
this.isMSIE = !!~this.context.navigator.userAgent.indexOf('MSIE');
}
// Find the users platform. We use this to interpret the meta key
// and ISO third level shifts.
// http://stackoverflow.com/q/19877924/577598
if (this.context.navigator && this.context.navigator.platform) {
this.isMac = contains(
this.context.navigator.platform,
['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K']
);
this.isIpad = this.context.navigator.platform === 'iPad';
this.isIphone = this.context.navigator.platform === 'iPhone';
this.isMSWindows = contains(
this.context.navigator.platform,
['Windows', 'Win16', 'Win32', 'WinCE']
);
}
//Create main element container
this.element = this.document.createElement('div');
this.element.classList.add('terminal');
@@ -846,7 +839,7 @@ Terminal.prototype.bindMouse = function() {
? ev.which - 1
: null;
if (self.isMSIE) {
if (self.browser.isMSIE) {
button = button === 1 ? 0 : button === 4 ? 1 : button;
}
break;
@@ -2724,7 +2717,7 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) {
// ^] - group sep
result.key = String.fromCharCode(29);
}
} else if (!this.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {
} else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {
// On Mac this is a third level shift. Use <Esc> instead.
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
result.key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
@@ -4879,15 +4872,6 @@ Terminal.charsets.ISOLatin = null; // /A
* Helpers
*/
function contains(el, arr) {
for (var i = 0; i < arr.length; i += 1) {
if (el === arr[i]) {
return true;
}
}
return false;
}
function on(el, type, handler, capture) {
if (!Array.isArray(el)) {
el = [el];
@@ -4942,8 +4926,8 @@ function indexOf(obj, el) {
function isThirdLevelShift(term, ev) {
var thirdLevelKey =
(term.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
(term.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
(term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
(term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
if (ev.type == 'keypress') {
return thirdLevelKey;
+2 -2
View File
@@ -387,7 +387,7 @@ describe('xterm.js', function() {
describe('On Mac OS', function() {
beforeEach(function() {
xterm.isMac = true;
xterm.browser.isMac = true;
});
it('should not interfere with the alt key on keyDown', function() {
@@ -436,7 +436,7 @@ describe('xterm.js', function() {
describe('On MS Windows', function() {
beforeEach(function() {
xterm.isMSWindows = true;
xterm.browser.isMSWindows = true;
});
it('should not interfere with the alt + ctrl key on keyDown', function() {