]> git.proxmox.com Git - mirror_xterm.js.git/blobdiff - src/xterm.js
Fix third level shifts for Mac OS and windows
[mirror_xterm.js.git] / src / xterm.js
index 2ba64e262d2ac9dcaac9c185ce75b1f07b221146..7f01e2a417ff0b42cbb7095d771fda7afb2a2a8a 100644 (file)
       * Parse User-Agent
       */
       if (this.context.navigator && this.context.navigator.userAgent) {
-        this.isMac = !!~this.context.navigator.userAgent.indexOf('Mac');
-        this.isIpad = !!~this.context.navigator.userAgent.indexOf('iPad');
-        this.isIphone = !!~this.context.navigator.userAgent.indexOf('iPhone');
         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/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today
+      */
+      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
       */
         return this.cancel(ev);
       }
 
-      if (result.cancel) {
+      if (isThirdLevelShift(this, ev)) {
+        return true;
+      }
+
+      if (result.cancel ) {
         // The event is canceled at the end already, is this necessary?
         this.cancel(ev, true);
       }
 
-      if (!result.key || (this.isMac && ev.metaKey)) {
+      if (!result.key) {
         return true;
       }
 
               // ^] - group sep
               result.key = String.fromCharCode(29);
             }
-          } else if ((!this.isMac && ev.altKey) || (this.isMac && ev.metaKey)) {
+          } else if (!this.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);
             } else if (ev.keyCode === 192) {
         return false;
       }
 
-      if (!key || ev.ctrlKey || ev.altKey || ev.metaKey) {
+      if (!key || (
+        (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev)
+      )) {
         return false;
       }
 
      * 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];
       return -1;
     }
 
+  function isThirdLevelShift(term, ev) {
+      var thirdLevelKey =
+          (term.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
+          (term.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
+
+      // Don't invoke for arrows, pageDown, home, backspace, etc.
+      return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
+    }
+
     function isWide(ch) {
       if (ch <= '\uff00') return false;
       return (ch >= '\uff01' && ch <= '\uffbe')